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
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 %>
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.
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.
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>
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