views:

214

answers:

2

I have the following models:

class FieldEntryValue < ActiveRecord::Base
  belongs_to :field_entry
end

and

class FieldEntry < ActiveRecord::Base
  belongs_to :field
  belongs_to :media
  has_many :field_entry_values, :dependent => :destroy
  accepts_nested_attributes_for :field_entry_values, :allow_destroy => true
end

The FieldEntriesController has the following methods:

  def new
    @field_entry = FieldEntry.new
    session[:media_id] = params[:media_id]
    session[:field_id] = params[:field_id]
    @field_entry.field = Field.find(params[:field_id])
    generate_fields(true)
    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @field_entry }
    end
  end

  def create
    @field_entry = FieldEntry.new(params[:field_entry])
    @field_entry.media_id = session[:media_id]
    @field_entry.field_id = session[:field_id]
    generate_fields(false)
    respond_to do |format|
      if @field_entry.save
        flash[:notice] = 'FieldEntry was successfully created.'
        format.html { redirect_to(@field_entry) }
        format.xml  { render :xml => @field_entry, :status => :created, :locati$
      else
        format.html { render :action => "new" }
        format.xml  { render :xml => @field_entry.errors, :status => :unprocess$
      end
    end
  end

  def generate_fields(do_build)
    @ftype = @field_entry.field.field_type.name
    if @ftype == 'string'
      @field_entry.field_entry_values.build if do_build
      @field_entry.field_entry_values[0].key='name'
    elsif @ftype == 'url'
      2.times{ @field_entry.field_entry_values.build } if do_build
      @field_entry.field_entry_values[0].key='name'
      @field_entry.field_entry_values[1].key='url'
    elsif @ftype == 'imdb'
      1.times{ @field_entry.field_entry_values.build } if do_build
      @field_entry.field_entry_values[0].key='value'
    end
  end

And I have a partial that is loaded by new and edit:

<% form_for(@field_entry) do |f| %>
  <%= f.error_messages %>

  <% f.fields_for :field_entry_values do |fv_f| %>
    <p>
    <%= fv_f.label :key %><br />
    <%= fv_f.text_field :value %>
    </p>
  <% end %>

  <p>
    <%= f.submit 'Save' %>
  </p>
<% end %>

The view should show a variable count fields depending on the type and with a given attribute key as label and value for the data.

For the type string as an example I need a label "Name" (that should be the key) and value

This works mostly except "fv_f.label :key" shows the string key and not the value of the key-field.

  1. How can I show the value of @field_entry.field_entry_values.key as label in the view?

  2. How can I make the Controller better/shorter. As an example, do I really need to set @field_entry.field_entry_values[0].key='name' in the new and the create method to to get it displayed in the view and saved in the database?

thanx for suggestions ;) I am a Rails newby I hope I did it not too wrong ;)

A: 

try this for 1.

<% form_for(@field_entry) do |f| %>
  <%= f.error_messages %>

  <% @field_entry.field_entry_values.each do |fv| %>

  <% f.fields_for fv do |fv_f| %>
    <p>
    <%= fv_f.label :value, fv.key %><br />
    <%= fv_f.text_field :value %>

    <%= # this will eliminate the need for generate_fields in create %>
    <%= fv_f.hidden_field :key %> 
    </p>
  <% end %>

  <% end %>
  <p>
    <%= f.submit 'Save' %>
  </p>
<% end %>
so1o
Looks good, but when I try it, I get the following:unknown attribute: field_entry_value{"commit"=>"Save", "field_entry"=>{"field_entry_value"=>{"value"=>"zzzzz", "key"=>"name"}}}when I revert it back to my view version it get saved.my view: Parameters: {"commit"=>"Save", "action"=>"create", "field_entry"=>{"field_entry_values_attributes"=>{"0"=>{"value"=>"2222222"}}}, "controller"=>"field_entries"}Strange, ok I guess thats because thats nested attributes and there can be more that one of it so the structure looks like that.
oh change <% f.submit %> to just <% submit_tag %>
so1o
did this solution work?
so1o
A: 

I found a better solution for my Problem 1, in rails 2.3 there is a object attribute for the fields_for loop target to get the object of the field:

<% form_for(@field_entry) do |f| %>
  <%= f.error_messages %>
    <% f.fields_for :field_entry_values do |fv_f| %>
    <p>
      <%= fv_f.label :value, fv_f.object.key%>
      <br />
      <%= fv_f.text_field :value %>
      <%= fv_f.hidden_field :key %>
    </p>
  <% end %>
  <p>
    <%= submit_tag %>
  </p>
<% end %>

Point 2 can not be improved much, maybe the generate_fields method could be loaded as a filter. But other than that, I don´t see anything at the moment, at least with this database structure.

But thanks for the help: so1o, at least the thing with hidden_field was helpfully.