I have a form for a delivery order that contains a form for a meal inside of it. A meal is made up of items, which are also objects. The form for a delivery looks as so...
<%= form_for #delivery do | f | %>
<%= f.label :address %>
<f.text_field :address $>
<% if #meal != nil %>
<% meal = #meal %>
<% else %>
<% meal = Meal.new %>
<% end %>
<%= f.fields_for meal %>
<%= render partial: "meals/form", locals: {selected_meal: meal} %>
<% end %>
<br>
<%= f.submit "Continue" %>
<% end %>
and the form for the meal looks as so
<label>Meal Name: (Optional) </label>
<%= f.text_field :name %>
<br>
<h4>-----------Pizzas------------</h4>
<%= f.collection_check_boxes :meal_item, Item.pizza_items, :id, :show %>
<br>
<h4>-------Cold Sandwiches-------</h4>
<%= f.collection_check_boxes :meal_item, Item.cold_items, :id, :show %>
<br>
<h4>-------Hot Sandwiches-------</h4>
<%= f.collection_check_boxes :meal_item, Item.hot_items, :id, :show %>
<br>
<h4>-----------Salads-----------</h4>
<%= f.collection_check_boxes :meal_item, Item.salad_items, :id, :show %>
<br>
<h4>------------Pastas------------</h4>
<%= f.collection_check_boxes :meal_item, Item.hot_items, :id, :show %>
<br>
<h4>-----------Chicken-----------</h4>
<%= f.collection_check_boxes :meal_item, Item.hot_items, :id, :show %>
<br>
<%= f.submit "Continue" %>
<% end %>
When the delivery form with the nested meal form is passed, it goes to the delivery # confirm action, and with the strong param, it looks like this...
def confirm
binding.pry
#delivery = Delivery.new()
if (SessionHelpers.is_logged_in?(session))
#credit = SessionHelpers.current_user(session).credit
end
end
private
def delivery_params
params.require(:delivery).permit(:address, :order_user_id, :total_price, :delivered, meal_attributes: [:name, items:[]])
end
Whenever the form is passed, the delivery_params only has the address passed, none of the meal attributes go through, yet they exist in the regular params. How can I fix this?
Probably coming from how you call your nested form.
Maybe try smething like :
<%= f.fields_for :meal do |meal_f| %>
And in your partial :
<%= meal_f.text_field :name %>
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
I hope they are good, need to do nested forms with the profile of a user and their respective car.
each user has their own profile:
class PerfilController < ApplicationController
before_filter :authenticate_user!
def index
end
def show
#usuario = current_user
#usuario.perfil ||= Perfil.new
#perfil = #usuario.perfil
end
def update
#usuario = current_user
#perfil = #usuario.perfil
respond_to do |format|
if #usuario.perfil.update_attributes(perfil_params)
format.html {redirect_to #usuario, notice: "Datos Actualizados" }
else
format.html {render action: "show"}
end
end
end
private
def perfil_params
params.require(:perfil).permit(:nombre, :apellido, :rut)
end
end
I want the fund to ensure that each time a user posts a car, you can update your profile. Deputy nested form
<%= simple_form_for(#auto) do |f| %>
<%= f.error_notification %>
<%=f.fields_for #perfil do |perfil_builder|%>
<p>
<%= perfil_builder.label :nombre %><br/>
<%= perfil_builder.text_field :nombre %>
<%= perfil_builder.label :apellido %><br/>
<%= perfil_builder.text_field :apellido %>
<%= perfil_builder.label :rut %><br/>
<%= perfil_builder.text_field :rut %>
</p>
<%end%>
<div class="form-inputs">
<%= f.association :region %>
<%= f.association :ciudad %>
<%= f.association :marca %>
<%= f.input :modelo %>
<%= f.input :version %>
<%= f.input :año %>
<%= f.input :patente %>
<%= f.association :tipo_transmision %>
<%= f.association :combustible %>
<%= f.association :tipo_vehiculo %>
<%= f.association :carroceria %>
</div>
<div class="form-actions">
<%= f.button :submit, :id => 'submit' %>
</div>
<% end %>
The problem is when you want to update does not change the user data but if you publish the article. the error in the console is: Unpermitted parameter: perfil
Best regards friends.
You are sending the request to the auto controller, hence the Unpermitted parameter: perfil error and failure to update.
You can add this to your Perfil controller:
has_many: :autos
accept_nested_attributes_for: :autos
Then in the view switch it around like this:
<%= simple_form_for(#perfil) do |f| %>
<%= f.error_notification %>
<%= f.label :nombre %><br/>
<%= f.text_field :nombre %>
...
<%=f.fields_for :auto do |auto_builder|%>
<p>
<%= auto_builder.association :region %><br/>
...
See this page for more info: http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
I have fields_for form for update like below:
<%= form_for #cuisine, url: {action: "update" } do |f| %>
<%= f.text_area :name %>
<% #cuisine.ingredients.each do |ing| %>
<%= f.fields_for ing do |ingredient_fields|%>
<%= ingredient_fields.text_area :name, :value=> ing.name %>
<%= ingredient_fields.hidden_field :_destroy%>
<%= link_to_remove_fields 'Remove this ingredient', f %>
<% end %>
<% end %>
<% end %>
my cuisines_controller:
def update
#cuisine = Cuisine.find(params[:id])
if #cuisine.update_attributes(cuisine_params)
redirect_to root_path
else
redirect_to edit_cuisine_path
end
end
Though this shows the form correctly (showing forms filled with #cuisine and its ingredients' info), after reloading the page the #cuisine object gets deleted even when I don't push the submit button.
Any idea what's going on or how to update nested attributes using fields_for?
Thanks in advance.
First you should just use fields_for like this:
<%= f.fields_for :ingredients do |ingredient_fields|%>
<%= ingredient_fields.text_area :name %>
<%= ingredient_fields.hidden_field :_destroy %>
<%= link_to_remove_fields 'Remove this ingredient', f %>
<% end %>
Second you should first check to see if the cuisine_params in your controller permit those attributes:
params.require(:cuisine).permit(:name, ingredients_attributes:[:id, :name, :_destroy])
Lastly, make sure your model has this accepts_nested_attributes_for :ingredients, allow_destroy: true
I followed this railscast.
Controller: project_sub_types_controller.rb
def new
#svn_repos = ['svn_software','svn_hardware']
#project_sub_type = ProjectSubType.new
#project_sub_type.repositories.build
end
def edit
#svn_repos = ['svn_software','svn_hardware']
#project_sub_type = ProjectSubType.find(params[:id])
end
Model: project_sub_type.rb
class ProjectSubType < ActiveRecord::Base
belongs_to :project_type
has_many :repositories, :dependent => :destroy
def repositories_attributes=(repos_attributes)
repos_attributes.each do |attributes|
repositories.build(attributes)
end
end
end
View: _form.html.erb
<%= form_for #project_sub_type, :html => {:class => 'project_subtype_form'} do |f| %>
<%= f.label :name, "Project sub type name" %>
<%= f.text_field :name %>
<% for repos in #project_sub_type.repositories %>
<%= fields_for "project_sub_type[repositories_attributes][]", repos do |repos_form| %>
<% #svn_repos.each do |repos| %>
<%= repos_form.check_box :repos_name, {}, "#{repos}", nil %>
<%= h repos -%>
<% end %>
<% end %>
<% end %>
<%= f.submit "Save"%>
This works perfectly during creation of a new record. But Y does the fields_for duplicates during edit. During create I see 2 checkboxes but during edit there are 4 checkboxes which duplicates the other 2 checkboxes. What am I doing wrong?
Update : The more times I click on edit and the duplication increases by 1.
<% for repos in #project_sub_type.repositories %>
<%= fields_for "project_sub_type[repositories_attributes][]", repos do |repos_form| %>
<% #svn_repos.each do |repos| %>
<%= repos_form.check_box :repos_name, {}, "#{repos}", nil %>
<%= h repos -%>
<% end %>
<% end %>
<% end %>
Get rid of that and do:
<%= f.fields_for :repositories do |repo_form| %>
<% #svn_repos.each do |rep| %>
<%= repo_form.check_box :repos_name, {}, rep, nil %>
<%= h rep -%>
<% end %>
<% end %>
Also get rid of repositories_attributes= method in your model and add accepts_nested_attributes_for :repositories
The railscast you linked is 7 years old. :)
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 %>