formtastic - subset of values in accepts_nested_attributes_for - ruby-on-rails

I have a model:
class Contact < ActiveRecord::Base
has_many :phones
accepts_nested_attributes_for :phones
end
I want to build 50 phone #s that users can add (there may already be phones 1 or 5, but I always want 50 available)
In my controller:
while contact.phones.length < 50
contact.phones.build({:phone_type_id => PhoneType['a_cool_type'].id})
end
In my view, I want to have 2 columns of phone #s 25 rows each
<%= semantic_form_for contact do |form| %>
<table width=50%>
<%= form.inputs :for => :phones[0..25] do |phone_form| %>
<td align="center"><%= phone_form.input :number, :label => false %></td>
....
<% end %>
</table>
<table width=50%>
<%= form.inputs :for => :phones[25..49] do |phone_form| %>
<td align="center"><%= phone_form.input :number, :label => false %></td>
....
<% end %>
</table>
<%end %>
Obviously the line:
<%= form.inputs :for => :phones[25..49] do |phone_form| %>
doesn't work, but it conveys my intention ( I hope). I want to have more control over how formtastic grabs the underlying object association.
The following works, but I can't do two columns easily without fancy css.
<%= form.inputs :for => :phones do |phone_form| %>
Any suggestions?
---------- Update ----
I was able to get around this in a roundabout way:
I built up a separate list of phone #s not as contact.phones.build, but Phone.new(:contact_id => contact.id) and store those in a list called #new_phones
Then my form looks like this:
<%= semantic_form_for #contact, :url => ..., do |f| %>
<% #new_phones[0...25].each_with_index do |phone, i| %>
<%= f.fields_for :phones, phone, :child_index => i do |phone_form| %>
<%= render "phone_fields", {:phone_form => phone_form, :phone => phone} %>
<%end%>
<% end %>
....
<% #new_phones[25...50].each_with_index do |phone, i| %>
<%= f.fields_for :phones, phone, :child_index => i+25 do |phone_form| %>
<%= render "phone_fields", {:phone_form => phone_form, :phone => phone} %>
<%end%>
<% end %>
<%end%>
This allowed me to display 25 phones on one part of the page, and 25 on another, with nested_attributes_for :phones working as expected on form submit.

I've always had problems with getting nested attributes working as I want but this may help resolve your issue.
Model:
class Contact < ActiveRecord::Base
has_many :phones
accepts_nested_attributes_for :phones
end
Controller:
See we're looping #contract.phones.build 50 times, this creates 50 new instances.
class Contact < ApplicationController
def new
#contact = Contact.new
25.times do
#contact.phones.build
end
end
end
View new.html.erb :
...
<%= p.semantic_fields_for :phones do |ec| %>
<%= ec.input :number %>
<% end %>
...
I did try a few attempts to intercept the loop, sadly with no definite clean avail.

Related

rails nested_forms error and logic

I'am trying to add some fields to my nested form. I've included the gem nested_forms (https://github.com/ryanb/nested_form).
For my prebuilt maps, it works fine, but i can't add new fields.
My controller:
def new
#people = Person.all
#vehicles = Vehicle.all
#roles = Role.all
#pratice_people = []
#people.each do |a|
if a.at1 == true
#pratice_people << a
end
end
#practice = Practice.new
#pratice_people.count.times { #practice.uebung_maps.build }
render action: "new"
end
and my form:
<% #runs = 0 %>
<%= f.fields_for :uebung_maps do |map| %>
<tr>
<%= map.hidden_field :role_id, :id => "role_id_#{#runs}" %>
<%= map.hidden_field :vehicle_id, :id => "vehicle_id_#{#runs}" %>
<%= map.hidden_field :person_id , :value => #pratice_people[#runs].id %><br/>
<td><%= #pratice_people[#runs].name %></td>
<td><%= map.select :role_id, options_from_collection_for_select(#roles, :id, :name), :include_blank => true %></td>
<td><%= map.select :vehicle_id, options_from_collection_for_select(#vehicles, :id, :name), :include_blank => true %></td>
<td><%= map.text_field :time %></td>
</tr>
<% #runs += 1 %>
<% end %>
<%= f.link_to_add "+" , :uebung_maps %>
If i try to access the page, i get following error report
Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id
Do I have to (or how to) create a logic to rerun Practice.uebung_maps.build?, because I thought this is done within the nested_forms gem....
First, make sure the models are created correctly.
class Practice < ActiveRecord::Base
has_many :uebung_maps
accepts_nested_attributes_for :uebung_maps
end
class UebungMap < ActiveRecord::Base
end
Second, make sure the form_for is nested correctly
<%= nested_form_for #practice do |f| %>
<%= f.fields_for :uebung_maps do |uebung_maps_form| %>
<%= uebung_maps_form.text_field :time %>
<% end %>
<p><%= f.link_to_add "+", :uebung_maps %></p>
<% end %>

Rails: Multi-model form won't write data to models

Ok this is driving me round the bend. I have three models [which are relevant to this quesiton]: Outfit, Outfit_relationship and Answer. Outfit is the parent model and the others are the childs. The Outfit model looks like this:
class Outfit < ActiveRecord::Base
attr_accessible :user_id, :outfit_origin_id, :outfit_parent_id, :outfitrelationship_id #review before going live
attr_accessible :item_id, :image_size_height, :image_size_width, :image_x_coord, :image_y_coord, :zindex, :outfit_id
attr_accessible :description, :question_id, :user_id, :outfit_id
has_many :answers
has_many :outfit_relationships
accepts_nested_attributes_for :outfit_relationships, :allow_destroy => :true
accepts_nested_attributes_for :answers
Note that the 2nd and 3rd attr_accessible are to access the attributes from the other models. I'm not sure this is absolutely necessary, some articles say it is, some say it isn't, so I put it in.
I've created a multi-model form for this data which I want to publish with one button. Here is the code:
<%= form_for(#outfit) do |post_outfit| %>
<%= post_outfit.fields_for #outfit.outfit_relationships do |build| %>
<table>
<tr>
<td>X Coord <%= build.text_area :image_x_coord, :size => '1x1' %></td>
<td>Y Coord <%= build.text_area :image_y_coord, :size => '1x1' %></td>
<td>Z Index <%= build.text_area :zindex, :size => '1x1' %></td>
<td>Height <%= build.text_area :image_size_height, :size => '1x1' %></td>
<td>Weight <%= build.text_area :image_size_width, :size => '1x1' %></td>
</tr>
</table>
<% end %>
<%= post_outfit.fields_for #outfit.answers do |build| %></br></br>
<%= image_tag current_user.fbprofileimage, :size => "40x40" %></br>
<%= current_user.name %></br>
Comment: <%= build.text_area :description, :size => '10x10' %>
<% end %>
<%= post_outfit.fields_for #outfit do |build| %> </br>
origin id: <%= build.text_area :outfit_origin_id, :size => '1x1' %></br>
parent id: <%= build.text_area :outfit_parent_id, :size => '1x1' %></br>
<% end %>
<div id="ss_QID_actions_container">
<%= post_outfit.submit "Submit checked", :class => "btn btn-small btn-primary" %>
</div>
<% end %>
And here are the relevant buts of the outfit controller:
def new
#outfit = Outfit.new
#outfit.save
#outfit.answers.build
#outfit.outfit_relationships.build
respond_to do |format|
format.html # new.html.erb
format.json { render json: #outfit }
end
end
def create
#outfit = Outfit.new(params[:id])
#comment = #outfit.answers.create(params[:answer])
#outfitrelationship = #outfit.outfit_relationships.create(params[:outfit_relationship])
redirect_to outfit_path(#outfit)
So the problem is nothing gets written into my database apart from the IDs. I'm sure I'm dong something stupid here, but can't figure out why.

Rails 3: nested form rendered with belongs_to association

I am struggling to get the nested form rendered with belongs_to association.
I was expecting the address fields in the "_form.html.erb" (below) to be rendered correct, but apparently it is not, and i just cant wrap my head around it to figure why!
Rails version: 3.09
here is the code.
Model:
Store.rb
class Store < ActiveRecord::Base
has_and_belongs_to_many :products
belongs_to :store_address, :foreign_key => "address_id", :class_name => "Address"
......
end
Address doesn't have any reference to Store model (it is independent)
Controller
stores_controller.rb
def new
#store = Store.new
#store.build_store_address
respond_with(#store)
end
View
new.html.erb
<% form_for(#store, :url => collection_url) do |f| %>
<%= render :partial => "form", :locals => { :f => f } %>
<p class="form-buttons">
<%= button t('continue') %>
</p>
<% end %>
_form.html.erb
<%=t(:store_name)%> : <%= text_field :store, :name %>
<%=t(:store_admin_email)%> : <%= text_field :store, :admin_email %>
<fieldset>
<legend><label><%=t(:address)%></label></legend>
<% f.fields_for :store_address do |address_form| %>
<table>
<tbody><tr>
<td width="200"><label><%=t(:line_1)%></label></td><td>
<%= address_form.text_area :address1, :rows => 2%>
</td>
</tr>
<tr>
<td><label><%=t(:line_2)%></label></td><td>
<%= address_form.text_area :address2, :rows => 2 %>
</td>
</tr>
<tr>
<td><label><%=t(:city)%></label></td><td>
<%= address_form.text_field :city %>
</td>
</tr>
.......
This renders the store name. but nothing on the address side. please help!
I think you missed an = at <% f.fields_for .... It should be <%= f.fields_for... .
This has happened to me so often in the past, missing this one thing, and then wondering why the nested form would not render.

Loading association data from database into edit.html.erb

I have the following one to many associations. Document has many Sections and Section has many Items.
class Document < ActiveRecord::Base
has_many :document_sections, :dependent => :destroy, :autosave => true
has_many :document_items, :through => :document_sections
end
class DocumentSection < ActiveRecord::Base
belongs_to :document
has_many :document_items, :dependent => :destroy, :autosave => true
end
class DocumentItem < ActiveRecord::Base
belongs_to :document_section
end
And the 'edit' action as follows :-
def edit
#document = Document.find(params[:id])
end
Here is the edit.html.erb
<h1>Edit!</h1>
<% form_for(#document) do |f| %>
<%= f.error_messages %>
<p>
<p> Header Comment <p/><br />
<%= f.text_field :comment %>
<%= f.hidden_field :uid %>
</p>
<% #document.document_sections.each do |section| %>
<% f.fields_for :section, :index => section.id do |s| %>
<p>
<%= s.hidden_field :seqnum, options = {:value => section.seqnum} %>
</p>
<% section.document_items.each do |item| %>
<% s.fields_for :item, :index => item.id do |i| %>
<p>
<%= i.text_area :comments, options = {:value => item.comments} %>
</p>
<% end %>
<% end %>
<% end %>
<% end %>
<p>
<%= f.submit "Submit Comments" %>
</p>
<% end %>
I have to specify the options hash with the value attribute set, for eg:
options = {:value => item.comments}
in order to show the item comments when I click the 'edit' link to modify the item comments. Shouldn't they be loaded by default, which seems to be the case for header comments.
Thanks for replying. Yes, i want to render the text area with the item.comments value from the database. The below code I had, does not load the comments.
<% s.fields_for :item, :index => item.id do |i| %>
<p>
<%= i.text_area :comments %>
</p>
<% end %>
can you explain me why
<%= text_area(:item, :comments) %>
works but
<%= i.text_area :comments %>
does not. Thanks much.
It seems your understanding of options is not correct. Here is what it is:
Additional options on the input tag can be passed as a hash with options
Which means that options sets attributes for the HTML tag.
You did not specify what exactly you want to do in the question, but I assume you want to render textarea tag with item.comments as a value. If so then you can use the 2nd parameter method (see the docs) and try this:
text_area(:item, :comments, :size => "20x30")
# => <textarea cols="20" rows="30" id="item_comments" name="item[comments]">
# #{#item.comments}
# </textarea>

Rails: Saving many new objects in a nested form

I have 2 models:
Video:
class Video < ActiveRecord::Base
belongs_to :user
has_many :thumbnails
attr_accessor :search, :saveable
accepts_nested_attributes_for :thumbnails, :allow_destroy => true
en
d
Thumbnail:
class Thumbnail < ActiveRecord::Base
belongs_to :video
end
I am using the YouTubeG gem in order to search for videos.
Each video that is returned by the search has a form in the view:
<% form_for :video, :url => videos_path, :html => { :class => :form } do |f| -%>
<%= f.hidden_field :url, :value => video.unique_id %>
<%= f.hidden_field :name, :value => video.title %>
<%= f.hidden_field :user_id, :value => current_user.id %>
<% if video.thumbnails.present? %>
<% f.fields_for :thumbnails, video do |t| %>
<% video.thumbnails.each do |thumbnail| -%>
<%=image_tag thumbnail.url %>
<%=t.text_field :url, :value => thumbnail.url %>
<% end -%>
<% end -%>
<% end %>
<%= f.submit "Save" %>
<% end -%>
The f.fields_for :thumbnails produces
<input type="hidden" value="http://i.ytimg.com/vi/s8eigkwmMEo/0.jpg" name="video[thumbnails][url]" id="video_thumbnails_url"/>
which seems to wrong because I want to save all thumbnails for this video.
When I try to save I get
ActiveRecord::AssociationTypeMismatch in VideosController#create
Parameters:
{"commit"=>"Save",
"video"=>{"name"=>"Karajan - Beethoven Symphony No. 7",
"url"=>"s8eigkwmMEo",
"user_id"=>"1",
"thumbnails"=>{"url"=>"http://i.ytimg.com/vi/s8eigkwmMEo/0.jpg"}}} < there should be 4 thumbnails
I found the correct answer:
<% f.fields_for "thumbnails_attributes[]", Thumbnail.new do |t| %>
instead of
<% f.fields_for :thumbnails, video do |t| %>
You should use index feature of the fields_for helper:
<% video.thumbnails.each do |thumbnail| -%>
<% f.fields_for "thumbnail[]", thumbnail do |t| %>
<%=image_tag thumbnail.url %>
<%=t.text_field :url, :value => thumbnail.url %>
<% end -%>
<% end -%>
Look through rails casts edipode trilogy about complex forms:
Episode 1

Resources