I try to create a furniture object, which is in relation by a has_many_and_belongs_to with stores, this is my model:
class Furniture < ActiveRecord::Base
attr_accessible :area, :description, :name, :size
has_and_belongs_to_many :stores
end
My problem is that I don't know how create a new furniture, because i try to associate furniture with one or more store with check box, but I obtain this error: undefined method merge for #<Store:0x007ff16ae27e40>.
These are my view with form and my controller with new and create action:
View:
<%= form_for #furniture do |f| %>
<%= f.label :name %>
<%= f.text_field :name %> <br><br>
<%= f.label :description %>
<%= f.text_field :description %> <br><br>
<%= f.label :size %>
<%= f.text_field :size %> <br><br>
<% #store.each do |store| %>
<div>
<%= f.check_box :stores, store %>
<%= store.name %>
</div>
<% end %>
<%= f.submit %>
<% end %>
Controller:
def new
#furniture = Furniture.new
#store = Store.order('name ASC')
end
def create
#furniture = Furniture.create(params[:furniture])
redirect_to admins_path
end
How can I solve it?? Have you some suggestion to create a new object with this relation ship??
Thank you very much
EDIT:
I have a join table between furniture and store
The has_and_belongs_to association adds a method collection_singular_ids= that for the current case will be #furniture.store_ids=. According to the docs
The collection_singular_ids= method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate.
So, you can use this idea to add the stores to your furniture. Replace
<% #store.each do |store| %>
<div>
<%= f.check_box :stores, store %>
<%= store.name %>
</div>
<% end %>
with
<% #store.each do |store| %>
<div>
<%= f.check_box :store_ids, {:multiple => true}, store.id, nil %>
<%= store.name %>
</div>
<% end %>
Related
I'm trying to create #booking and #booking.build_passenger in form_for with nested attributes in Rails 4.2.1
The error I get:
As you see in the console at the bottom of the image:
1. params.require(:booking) returns a Hash-like params for #booking
2. params.class returns ActionController::Parameters
As the params seems to behave correctly, IMO the problem hides somewhere in the form:
<%= form_for #booking do |f| %>
<%= f.hidden_field :flight_id, value: params[:flight_id] %>
<%= render 'flights/flight_info' %>
<div class="field">
<b><%= f.label :num_tickets, "Tickets" %></b>
<%= f.select(:num_tickets, #num_tickets) %>
</div><br>
<h4>Passenger info:</h4>
<%= f.fields_for #booking.build_passenger do |pass| %>
<div class="field">
<%= pass.label :name %>
<%= pass.text_field :name %>
</div>
<div class="field">
<%= pass.label :email %>
<%= pass.email_field :email %>
</div>
<% end %>
<%= f.submit 'Book Flight!' %>
<% end %>
Booking model:
class Booking < ActiveRecord::Base
belongs_to :flight
belongs_to :passenger
accepts_nested_attributes_for :passenger
end
Question: Where and how do I have to edit my code for the app to start creating #booking instances + #booking.build_passenger()
Your booking_params needs to be something like:
def booking_params
params.require(:booking).permit(:flight_id, :num_tickets, passenger_attributes: [:id, :name, :email])
end
Before asking this, I have already tried with the solution detailed here, but it didn't work.
context: 2 models, Idea and Project. 1 idea belongs to 1 project, 1 projects has many ideas.
I want to create a form to create ideas that have fields of ideas but also to specify which Project they belong to, by indicating the project_id field. I'm doing it with accepts_nested_attributes_for
Issue: I'm not being able to grab the project_id when creating a new idea from a form. From the console I see that a new idea has been saved, but project_id for that idea always returns nil
code:
ideas_controller.rb
# GET /ideas/new
def new
#idea = Idea.new
#idea.build_project
respond_to do |format|
format.html # new.html.erb
format.json { render json: #idea }
end
models> idea.rb
class Idea < ActiveRecord::Base
belongs_to :project
accepts_nested_attributes_for :project
mount_uploader :picture, PictureUploader
validates :name, presence: true, allow_blank: false
end
_form.html.erb
<%= form_for(#idea) do |f| %>
<% f.fields_for :project do |project_fields| %>
<% if #idea.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#idea.errors.count, "error") %> prohibited this idea from being saved: </h2>
<ul>
<% #idea.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :description %><br>
<%= f.text_area :description %>
</div>
<div class="field">
<%= f.label :picture %><br>
<%= f.file_field :picture %>
</div>
<div class="field">
<%= f.label :project %><br>
<%= f.number_field :project_id, :class=>"Number" %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
<% end %>
"Nested attributes allow you to save attributes on associated records through the parent", according to the documentation. you are doing it through the child, which I don't think is possible.
So either move the accepts_nested_attributes_for to the parent model and use the parent's form to create the parent fields along with the child field. so you'll be creating project and idea through the projects_controller and projects/_form.html.erb
or opt out for something else.
without using accepts_nested_attributes_for, add project_ids to your ideas params attributes as an empty array:
def idea_params
params.require(:idea).permit(:name, :project_ids => [])
end
app/views/ideas/_form.html.erb:
<div>
<%= idea.label 'File under at least one project' %>
<% Project.all.order(name: :asc).each do |project| %>
<div>
<%= check_box_tag "idea[project_ids][]", project.id %>
<%= project.name %>
</div>
</div>
this code will give you checkboxes of your projects to select. this means first you have to create the projects separely in project's own controller and form. so you are not using nesting attributes.
I'm having issues with the implementation of a nested form for a model with has_many through relationship
I have 3 models: Reservation, Table and Collection (Join Model for these two)
In my Reservation Controller I have these two methods:
def new
#reservation = Reservation.new
#tables = Tables.all
#tables.size.times {#reservation.collections.build}
end
and
def reservation_params
params.require(:reservation).permit(:name, collections_attributes: [ :table_id, :units_sold],
tables_attributes: [:units, :title])
end
my form view is as following:
<%= form_for [current_user, #reservation] do |f| %>
<header>
<h1>Make Reservation</h1>
</header>
<%= f.text_field :name, placeholder: "Name" %>
<%= f.fields_for :collections do |builder| %>
<%= render 'nested_form', :f => builder %>
<% end %>
<%= f.submit "Save" %>
<% end %>
and my _nested_form.html.erb file:
<%= f.number_field :units_sold, placeholder: "Units" %>
<%= check_box_tag :table_id %>
My problem is, whenever I save a new entry on the database he assigns the same table_id to all collections association, e.g:
I want to receive the Parameters hash such as:
"collections_attributes"=>{"0"=>{"units_sold"=>"5", "table_id"=>"1"}, "1"=>{"units_sold"=>"6", "table_id"=>"2"}}}
Instead what I'm getting is:
"collections_attributes"=>{"0"=>{"units_sold"=>"5", "table_id"=>"1"}, "1"=>{"units_sold"=>"6", "table_id"=>"1"}}}
How do I fix this for it to give the correct table_id for each collection?
It would be better if you provide your models' snippet that shows their associations.
Anyway, according to your form; One Reservation has many tables through collections.
change:
<%= check_box_tag :table_id %>
to
<% #tables.each do |table| %>
<li>
<%= f.radio_button :table_id %>
<%= f.label :table_id, table.name %>
</li>
<% end %>
By this, you will be able to choose one table from all for each collection using radio button.
Hope this will help!
I have these two models
class Invoice < ActiveRecord::Base
has_many :items
accepts_nested_attributes_for :items
...
end
class Item < ActiveRecord::Base
belongs_to :invoice
def total
price * quantity
end
...
end
and this nested (!) form that posts to both models:
<h1>Add an Invoice</h1>
<%= form_for #invoice do |f| %>
<p>
<%= f.label :recipient %>
<%= f.text_field :recipient %> </p>
<p>
<%= f.label :date %>
<%= f.text_area :date %>
</p>
<h2>Items</h2>
<p>
<%= f.fields_for(:items) do |f| %>
<%= f.label :description %>
<%= f.text_field :description %>
<%= f.label :price %>
<%= f.text_field :price %>
<%= f.label :quantity %>
<%= f.text_field :quantity %>
<%= f.label :total %>
<%= f.total %><!-- this method call is not working! -->
<% end %>
</p>
<%= f.submit %>
<% end %>
How can I do calculations on my items within the form?
In my Items model I have this method:
def total
price * quantity
end
However, in the form I can't get it to work with f.total. I keep getting this error:
undefined method `total' for #<ActionView::Helpers::FormBuilder:0x10ec05558>
What am I missing here?
You are calling a method not on your model object, but on f, which is a form helper (ActionView::Helpers::FormBuilder). Error message gives a hint to this.
To call on the item, you need to replace
<%= f.total %>
with
<%= f.object.total %>
In my Ruby on Rails application I want to allow the adding/editing of a nested model which itself has an associated model.
model Survey
string title
has_many questions
model Question
string question
belongs_to category
model Category
string name
For the sake of argument let's assume that the user should always have to enter a new category when entering a question (I couldn't come up with a better example, sigh).
In my model/survey/edit.html.erb I have a working setup for adding questions and saving them. However when I added the Category model to the picture, I now face the problem that when adding a new Question, there is no corresponding Category name-field displayed. I suspect this is because even though I do call Question.new, I do not call question.category.build - and I have no idea where/how to do that.
My edit.html.erb:
<h1>Editing Survey</h1>
<%= render :partial => 'form' %>
My _form.html.erb:
<% form_for(#survey) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :title %><br />
<%= f.text_field :title %>
</p>
<div id="questions">
<% f.fields_for :questions do |q| %>
<%= render :partial => 'question', :locals => { :pf => q } %>
<% end %>
</div>
<%= add_a_new_child_link("New question", f, :questions) %>
<% end %>
My _question.html.erb:
<div class="question">
<%= pf.label :question %>
<%= pf.text_field :question %>
<% pf.fields_for :category do |c| %>
<p>
<%= c.label :name, "Category:" %>
<%= c.text_field :name %>
</p>
<% end %>
</div>
A quick fix for your situation is to use virtual attributes.
EG, in your Question model:
def category_name=(new_name)
if category then
category.name = new_name
else
category = Category.new(:name => new_name)
end
end
def category_name
return category.name if category
""
end
In your _question, there no need to use nested form. Just add something like:
<%= pf.text_field :category_name %>
I didn't test it, but you probably caught the ideea.