Creating nested form in Rails 3.1 - ruby-on-rails-3

I am trying to render a partial which I have set up as the following. I have am also trying to create a nested form whereby I have included accepts_nested_attributes_for :user in my hospital_bookings model. I seem to be getting the following error:
NameError in Rota_days#index
Showing
C:/Users/home/Desktop/Portal/app/views/rota_days/index.html.erb
where line #31 raised:
undefined local variable or method `hospital_booking' for
which is pointing to the following line <%= render :partial => "booking_dialog", :locals => { :booking => hospital_booking.new } %> of my index.html.erb as shown below. I thought it was something to do with my pluralization. By changing hospital_bookings.new to hospital_booking.new but this did not work
_booking_dialog.html.erb
<%= form_for booking do |f| %>
<%= f.fields_for :user do |f| %>
<br/>
<%= f.label :name %>
<br/>
<%= f.text_field :name %>
<%= f.hidden_field :hospital_id %>
<%= f.hidden_field :id unless booking.new_record? %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

hospital_booking.new is nonsensical: you have no local variable named hospital_booking. If you want a new instance of the HospitalBooking model, then you want HospitalBooking.new.
So:
<%= render :partial => "booking_dialog", :locals => { :booking => HospitalBooking.new } %>
Update (from the comments)
In the booking_dialog form partial, you need to put the name attribute on the associated user record inside a fields_for block, to distinguish it from the fields for the parent (booking):
<%= form_for booking do |f| %>
<%= fields_for :user do |user_fields| %>
<%= user_fields.label :name %>
<%= user_fields.text_field :name %>
<% end %>
<%= f.hidden_field :hospital_id %>
<%= f.hidden_field :id unless booking.new_record? %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
p.s. it seems very strange that you have a hidden field for the :id in here. You shouldn't need that.

Related

rails form partial for new and edit on same page

I am running into issues trying to separate a form from a view into a partial. I want to use the same form for the new and edit views. These are both on the same page. The new model form is at the top of the page and uses a variable that I set in the controller.
<%= form_for #new_hire do |f| %>
<%= render :partial => 'new_hire_requests/form', :locals => {:f => f} %>
<% end %>
I then have a partial for the pending approvals that gets rendered by another partial
<%= render :partial => 'pending_approval', :collection => #pending_approval %>
And inside the pending approval partial I have this
<%= form_for pending_approval do |f| %>
<%= render :partial => 'new_hire_requests/form', :locals => {:f => f} %>
<% end %>
This is throwing an error
undefined method `new_hire_request_path' for #<#<Class:0x0000010488ac98>:0x0000010223ffc0>
Is there a way to re use the form code for both a new and edit form on the same page?
Controller Logic
#new_hire = NewHireRequest.new
#new_hire_requests = current_user.new_hire_requests
#pending_approval = #new_hire_requests.select{|p| p.status == 'pending_hr_approval' || p.status == 'pending_exec_approval'}
Partial code
<%= render 'shared/error_messages', object: f.object %>
<fieldset class="first">
<%= f.label :first_name, "First Name" %>
<%= f.text_field :first_name %>
</fieldset>
<fieldset>
<%= f.label :last_name, "Last Name" %>
<%= f.text_field :last_name %>
</fieldset>
<%= f.submit "Submit for Approval <i class='icon-share-alt icon-white'></i>",
class: "button_green" %>
add resources new_hire_requests in the routes and get done with it .

RoR: why am I getting undefined method 'hidden_field_tag'?

right now I have two forms in a row
<section>
<%= render 'shared/micropost_form_purchase' %>
<%= render 'shared/micropost_form_sale' %>
</section>
then for _micropost_form_purchase.html.erb
<%= form_for(#micropost) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= f.hidden_field_tag :type, :value => "purchase" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
and for _micropost_form_sale.html.erb I have
<%= form_for(#micropost, :html => { :id => "sale" }) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field no-indent">
<%= f.text_area :content, placeholder: "What's something else you want to buy?" %>
<%= f.hidden_field_tag :type, :value => "sale" %>
</div>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>
so I want the first micro post to automatically become a purchase micropost (I have a column in the micropost database called type that is a string that I want to depict either sale or purchase) and for the second one I want it to become a sale micropost. I was using hidden_field_tag because I thought you didn't have to define it in the controller, but am I wrong? Is hidden_field more appropriate? how can I use hidden_field_tag?
You can use:
<%= f.hidden_field :type, :value => "sale" %>
or:
<%= hidden_field_tag 'micropost[type]', "sale" %>
but not:
<%= f.hidden_field_tag :type, :value => "sale" %>
Using f.hidden_field will use the value from the variable #micropost, whereas hidden_field_tag will not use that.
It should be f.hidden_field not f.hidden_field_tag as you're using the model's form helpers :)

Couldn't find <model> without an ID, with nested attributes

I have what should be a super simple form which I'm trying to use to update multiple records at once. I'm on Rails 3. I've been through all of the railscasts, etc and am pulling my hair out at this point. I'm using Devise, and have a contacts controller. Users have_many :contacts, and accepts_nested_attributes_for :contacts. The form looks like:
<%= form_for #user, :url => '/updateusercontacts' do |i| %>
<%= i.fields_for :contacts do |f| %>
<%= f.label :first_name %>
<%= f.text_field :firstname %>
<%= f.label :last_name %>
<%= f.text_field :lastname %>
<%= f.label :phone_number %>
<%= f.text_field :phonenumber %>
<%= f.label :user_id %>
<%= f.text_field :id %>
<p>
<% end %>
The form displays properly, but then on submit I get "Can't find Contact without an ID". The controller looks like:
def updatecontacts
#contacts = Contact.find(params[:id])
#contacts.each do |contact|
contact.update_attributes(params[:id])
end
render '/home'
end
The parameters seem correct, and the id's seem to be present and correct, but I can't get the save to work! I'm sure I'm missing something obvious here.
Try to remove the fields_for and when you invoke your find, use this [:user][:contacts]
your code should look like this.
View:
<%= form_for #user, :url => '/updateusercontacts' do |i| %>
<%= i.label :first_name %>
<%= i.text_field :firstname %>
<%= i.label :last_name %>
<%= i.text_field :lastname %>
<%= i.label :phone_number %>
<%= i.text_field :phonenumber %>
<%= i.label :user_id %>
<%= i.text_field :id %>
<p>
<% end %>
Controller
def updatecontacts
#contacts = Contact.find(params[:user][:contacts])
#contacts.each do |contact|
contact.update_attributes(params[:user][:contacts])
end
render '/home'
end
Hope this works.

Rails3 acts_as_taggable with a form

I've just started working with the acts_as_taggable gem. Really liking it so far, but I am a bit unclear about how to use this gem with a form.
class Photo < ActiveRecord::Base
acts_as_taggable_on :tags
end
In my form for Photos I am trying to implement a series of checkboxes for the user to assign tags to their photo:
<%= f.label :tag_list %>
<%= f.check_box :tag_list, "landscape" %>
<%= f.check_box :tag_list, "people" %>
When viewing the form I get this error:
NoMethodError in Photos#edit
...line #19 raised:
undefined method `merge' for "landscape":String
Extracted source (around line #19):
18: <div class="float_tag">
19: <%= f.check_box :tag_list, "landscape" %>
Any thoughts as to how I should create my form?
I'm assuming your <form> looks something like this:
<%= form_for(#photo) do |f| %>
<%= f.label :tag_list %>
<%= f.check_box :tag_list, "landscape" %>
<%= f.check_box :tag_list, "people" %>
<% end %>
You should change up your f.checkbox lines a bit:
<%= form_for(#photo) do |f| %>
<%= f.label :tag_list %>
<%= f.check_box :tag_list, { :multiple => true }, 'landscape', nil %>
<%= f.check_box :tag_list, { :multiple => true }, 'people', nil %>
<% end %>
Which will post something like this when submitted (with only people selected, for example):
{ :post => { :tag_list => ['', 'people'] } }
For anyone trying to get this to work with Rails 4 and strong parameters, I also had to permit the the tag_list param as an array.
params.require(:clip).permit(
:name, :other_params, { tag_list: [] }
)

options within nested form

Trying to make a nested form, which is working fine so far, except i need to put some dropdowns for the user to choose, as well as maybe make a couple of validations, however it seems nothing gets out of the form properly and keep getting errors no matter what I try.
three models.
--configuration
has_many :configoptions
accepts_nested_attributes_for :configoptions
--configoption
belongs_to :configuration
has_many :items
and item
belongs_to :configoption
scope :sorted, order('items.position ASC')
Now, so far I'm creating a nested form, looping through the configoptions, but for each option is possible there's more than one item. So I want to make a drop-down for those options where this is the case.
In my view i have:
<p>
<th>Elements</th>
<th>Quantity</th>
</p>
<%= form_for #config, :url => {:action => 'show', :id => #config.id} do |f| %>
<%= f.fields_for :configoptions do |fp| %>
<p>
<% if :items.count > 1 %>
<%= fp.text_field :name %>
<% else %>
<% fp.select(:items, :name)%>
<% end %>
<%= fp.text_field :quantity %>
</p>
<% end %>
<%= f.submit %>
<% end %>
I get an error obviously telling me that it can't count the :items.
How do you think I can make this work?
Thanks!
<%= form_for #config, :url => {:action => 'show', :id => #config.id} do |f| %>
<%= f.fields_for :configoptions do |fp| %>
<%= fp.text_field :id %>
<%= fp.text_field :name %>
<%= fp.text_field :quantity %>
<% end %>
<%= f.submit %>
<% end %>
OK, I think I figured it out, at least it seems to be doing what I want now.
I modified the view to pass the instance of the configoption into the nested form itself to be able to create the drop downs.
<% for configoption in #config.configoptions %>
<%= f.fields_for :configoptions, configoption do |fp| %>
<p>
<% if configoption.items.count > 1 %>
<%= fp.select (:name, options_from_collection_for_select(configoption.items.sorted, 'name', 'name'))%>
<% else %>