I need to render a sub form in my main form and i tried to render it in the main form
this issue has relation with three models
Class PrdItem model< ActiveRecord::Base
has_one :prd_allisland_flat_delivery, dependent: :destroy, inverse_of: :prd_item
accepts_nested_attributes_for :prd_allisland_flat_delivery, allow_destroy: true
has_many :prd_province_vise_deliveries, dependent: :destroy, inverse_of: :prd_item
accepts_nested_attributes_for :prd_province_vise_deliveries, allow_destroy: true
end
Class PrdAllislandFlatDelivery < ActiveRecord::Base
belongs_to :prd_item
end
Class PrdProvincevisedelivery < ActiveRecord::Base
belongs_to :prd_item
end
In prd_item/new.html.erb the _form.html.erb is rendered
in that _form.html.erb
i wrote this code fragment
<%= p.fields_for :prd_allisland_flat_deliveries do |i| %>
<%= render(:partial => 'prd_allisland_flat_delivery_field', :locals => {:f => p})%>
<% end %>
this is a fragment of that form partial
<div class="col-md-4">
<%= f.text_field(:delivery_period, {placeholder: '0', class: 'form-control input_border input_field_text_align_right'})%>
</div>
that gives me
undefined method
`delivery_period' for #
error
in _form.html.erb
<%= p.fields_for :prd_allisland_flat_deliveries do |i| %>
<%= render(:partial => 'prd_allisland_flat_delivery_field', :locals => {:f => i})%>
<% end %>
and
<%= f.text_field(:delivery_period, {placeholder: '0', class: 'form-control input_border input_field_text_align_right'})%>
Related
i'm developing in Rails 4 with bootstrap rails forms and i'm trying to make a form that saves a product to a table. The product has many inputs and the input could belong to many products. The DB is postgres.
My main issue here is to save the product_id and the input_id to a join table I've created, named "productinput". this could be an example of what i'm trying to accomplish:
productinput table values example to generate each time i generate a new product with many inputs selected from a checkbox select:
product_id: 1 input_id: 1
product_id: 1 input_id: 2
product_id: 1 input_id: 3
product_id: 1 input_id: 4
I've done most of the configuration in my app. please take a look:
**productinput model**
class Productinput < ActiveRecord::Base
belongs_to :input, inverse_of: :productinputs
belongs_to :product, inverse_of: :productinputs
validates_presence_of :user_id
validates_presence_of :input_id
validates_presence_of :product_id
end
**product model**
class Product < ActiveRecord::Base
has_many :productinputs, inverse_of: :product, :dependent => :destroy
has_many :inputs, :through => :productinputs
accepts_nested_attributes_for :inputs
accepts_nested_attributes_for :productinputs, :allow_destroy => true
has_many :clientproducts, inverse_of: :product
has_many :worktasks, inverse_of: :product
validates_presence_of :user_id
accepts_nested_attributes_for :clientproducts, :allow_destroy => true
accepts_nested_attributes_for :worktasks
end
**input model**
class Input < ActiveRecord::Base
has_many :productinputs, inverse_of: :input, :dependent => :destroy
has_many :products, :through => :productinputs
accepts_nested_attributes_for :productinputs, :allow_destroy => true
has_many :inputproviders, inverse_of: :input
validates_presence_of :user_id
accepts_nested_attributes_for :inputproviders
end
Then the product form i'd like to have updated with the Input field to add inputs dinamically with a multiple select:
<%= bootstrap_form_for( #product, layout: :horizontal, label_col: "col-sm-2 hide", control_col: "col-sm-12", label_errors: true) do |f| %>
<div class="container-fluid">
<div class="row">
<%= f.alert_message "Please fix the errors below." %>
</div>
<div class="row">
<div class="col-xs-12">
<%= f.text_field :name, hide_label: true, placeholder: "Name", icon: "tag" %>
<%= f.text_field :description, hide_label: true, placeholder: "Description", icon: "align-justify" %>
<%= f.text_field :stock, hide_label: true, placeholder: "Stock", icon: "book" %>
<%= f.text_field :price, hide_label: true, placeholder: "Price", icon: "usd" %>
</div>
</div>
<div class="row text-center">
<%= f.submit "Submit Product", :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
products_path, :class => 'btn btn-default' %>
</div>
</div>
i've tried cocoon, nested_form, formtastic, simple_form gems, many tutorials and more that 2 weeks investigating this and i still don't understand how can i manage to do this, would you give me a hand please ?
Thanks,
This is how i manage to create children records in the join table from the parent form view:
Models:
class Product < ActiveRecord::Base
has_many :productinputs, :dependent => :destroy
has_many :inputs, through: :productinputs
accepts_nested_attributes_for :productinputs, :allow_destroy => true
has_many :clientproducts, inverse_of: :product
has_many :worktasks, inverse_of: :product
validates_presence_of :user_id
end
class Productinput < ActiveRecord::Base
belongs_to :product
belongs_to :input
#validates_presence_of :user_id
#validates_presence_of :input_id
#validates_presence_of :product_id
end
class Input < ActiveRecord::Base
has_many :productinputs
has_many :products, through: :productinputs
accepts_nested_attributes_for :productinputs, :allow_destroy => true
has_many :inputproviders, inverse_of: :input
validates_presence_of :user_id
accepts_nested_attributes_for :inputproviders
end
Controller:
Key here, the :inputs_ids[] fills up with an array of input elements from the "check_box_tag "product[input_ids][]"" in the form:
def product_params
parameters = params.require(:product).permit(:name, :description, :stock, :price, :input_ids => [], productinputs_attributes: [:user_id, :quantity])
parameters[:user_id] = current_user.id
parameters
end
Form:
<%= simple_form_for #product, defaults: { input_html: { class: 'form-horizontal' } } do |f| %>
<div class="row"> <%= f.error_notification id: 'user_error_message', class: 'form_error' %>
</div>
<div class="row">
<div class="col-xs-12 col-md-6">
<%= f.input :name, placeholder: 'Product Name', error: 'Username is mandatory, please specify one', label: false %>
<%= f.input :description, placeholder: 'Enter Description', label: false %>
<%= f.input :stock, placeholder: 'Stock', label: false %>
<%= f.input :price, placeholder: 'Price', label: false %>
</div>
<div class="col-xs-12 col-md-6">
<%= hidden_field_tag "product[input_ids][]", nil %>
<% Input.where("user_id = ?", current_user.id).each do |input| %>
<%= check_box_tag "product[input_ids][]", input.id,
#product.input_ids.include?(input.id), id: dom_id(input) %>
<%= label_tag dom_id(input), input.name %><br>
<% end %>
</div>
</div>
<div class="row text-center">
<%= f.button :submit, :class => 'btn btn-primary' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
products_path, :class => 'btn btn-default' %>
</div>
<% end %>
Hope this helps anyone who has the same issue that i did.
Sorry if some people didn't understand what i was looking for.
P.S: just to let you know, i could simplify the multiple checkbox with simple form from this:
<%= hidden_field_tag "product[input_ids][]", nil %>
<% Input.where("user_id = ?", current_user.id).each do |input| %>
<%= check_box_tag "product[input_ids][]", input.id, #product.input_ids.include?(input.id), id: dom_id(input) %>
<%= label_tag dom_id(input), input.name %><br>
<% end %>
to this:
<%= f.association :inputs, :as => :check_boxes %>
Does anybody know how to handle these attributes in the controllers new and create action?
(byebug) params
{"utf8"=>"V", "authenticity_token"=>"Wex9nnFigOviySzjfPN6zw==",
"recipe"=>{"name"=>"Cupcake"},
"name"=>{"ingredient_id"=>"2"},
"quantity"=>{"amount"=>"zwei"},
"commit"=>"Create", "controller"=>"recipes", "action"=>"create"}
I don't know how to create the quantities record with the value from Ingredient in recipe#new
("name"=>{"ingredient_id"=>"2")
Two records should be created (Recipe and Quantity).
Recipe
name
Quantity
ingredient_id
recipe_id
amount
Ingredient
name
class Recipe < ActiveRecord::Base
belongs_to :user
has_many :quantities
has_many :ingredients, through: :quantities
accepts_nested_attributes_for :quantities, :reject_if => :all_blank, :allow_destroy => true
accepts_nested_attributes_for :ingredients
end
class Ingredient < ActiveRecord::Base
has_many :quantities
has_many :recipes, :through => :quantities
end
class Quantity < ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
accepts_nested_attributes_for :ingredient, :reject_if => :all_blank
end
<%= form_for(#recipe) do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= form_for(#recipe.quantities.build) do |g| %>
<%= select("name", "ingredient_id", Ingredient.all.collect {|p| [ p.name, p.id ] }, {include_blank: 'Auswählen'}) %>
<%= g.label :amount %>
<%= g.text_field :amount %>
<%= g.submit "Create" %>
<% end %>
<% end %>
I replaced:
<%= form_for(#recipe.quantities.build) do |g| %>
with:
<%= f.fields_for :quantities, #recipe.quantities.build do |g| %>
And put submit action to form level after fields_for:
<%= f.submit "Create" %>
Following the Cocoon wiki for implementing The look-up or create :belongs_to I'm receiving the error: wrong number of arguments (1 for 0). I'm not exactly sure what its referring to being that I'm following the tutorial verbatim aside from using slim as my precompiler. Here's what my code looks like:
Models
class Project < ActiveRecord::Base
belongs_to :user
has_many :tasks
accepts_nested_attributes_for :tasks, :reject_if => :all_blank, :allow_destroy => true
accepts_nested_attributes_for :user, :reject_if => :all_blank
end
class User < ActiveRecord::Base
has_many :projects
end
Projects Form
<%= simple_form_for #project do |f| %>
<%= f.input :name %>
<%= f.input :description %>
<h3>Tasks</h3>
<div id="tasks">
<%= f.simple_fields_for :tasks do |task| %>
<%= render 'task_fields', :f => task %>
<% end %>
<div class="links">
<%= link_to_add_association 'add task', f, :tasks %>
</div>
</div>
<div id="user">
<div id="user_from_list">
<%= f.association :user, collection: User.all(:order => 'name'), :prompt => 'Choose an existing user' %>
</div>
<%= link_to_add_association 'add a new person as owner', f, :user %>
</div>
<%= f.submit %>
<% end %>
Projects Controller
...
def project_params
params.require(:project).permit(:name, :description, tasks_attributes: [:id, :description, :done, :_destroy], user_attributes: [:id, :name])
end
Backtrace
app/views/projects/_form.html.erb:16:in `block in _app_views_projects__form_html_erb___3132123068035883478_70337216288160'
app/views/projects/_form.html.erb:1:in `_app_views_projects__form_html_erb___3132123068035883478_70337216288160'
app/views/projects/new.html.erb:3:in `_app_views_projects_new_html_erb__2418839848133678570_70337176808940'
ActiveRecord#all has been changed in rails 4 - this is now doing what scoped used to do. It does not expect any extra params. Instead of User.all(order: 'name') do:
User.order(:name)
I have 3 models; Quote, Item, and Product.
My quote/new.html.erb is set up to render a partial which contains the item form, and in that item form a partial is rendered to choose a product.
the error: ActiveModel::MassAssignmentSecurity::Error in QuotesController#create
"Can't mass-assign protected attributes: products"
(I edited out irrelevant stuff in the following)
Quote.rb
class Quote < ActiveRecord::Base
attr_accessible :items_attributes
has_many :items, :dependent => :destroy
accepts_nested_attributes_for :items
end
Item.rb
class Item < ActiveRecord::Base
attr_accessible :price, :product_attributes
belongs_to :quote
belongs_to :product
accepts_nested_attributes_for :product
end
Product.rb
class Product < ActiveRecord::Base
attr_accessible :name, :item_make
has_many :items
accepts_nested_attributes_for :items
end
new.html.erb
<%= simple_nested_form_for #quote do |m| %>
<%= m.simple_fields_for :items, :html => { :multipart => true } do |quoteform| %>
<%= render "form", f: quoteform %>
<% end %>
<%= m.link_to_add "Add an item", :items %>
<%= m.button :submit %>
<% end %>
_form.html.erb
<%= f.simple_fields_for :products, :html => { :multipart => true } do |x| %>
<% render "layouts/styleselect", g: x %>
<% end %>
_styleselect.html.erb
<% g.hidden_field :item_make, :value => #item.make %>
<%= g.input :name, collection: Product.where(:item_make => 1), label: false, input_html: {:id=>"sst_style"} %>
So basically the nested form goes Quote->Item->Product, but item belongs to product, which maybe is causing the problem? I tried adding product_attributes or products_attributes to both the item model and the quote model, and the same with accepts_nested_attributes_for product(s).
Any help would be appreciated, thanks.
Looks like you need to make products singular.
<%= f.simple_fields_for :product, :html => { :multipart => true } do |x| %>
<% render "layouts/styleselect", g: x %>
<% end %>
You currently have:
<%= f.simple_fields_for :products, :html => { :multipart => true } do |x| %>
Im trying to update some nested params from a form. I can see that the parameters im getting from the form is correct, however the database dont get updated.
the view
<% form_for #order do |f| %>
<% f.fields_for :itemgroups do |ff, i| %>
<% ff.fields_for :items do |fff| %>
<%= ff.text_field :text, :id => "textField", :disabled => true %>
<%= ff.text_field :price, :class => "priceField", :disabled => true %>
<%= fff.check_box :registered, :class => i %>
<% end %>
<% end %>
<%= submit_tag 'Save', :disabled_with => "Saving..." %>
<% end %>
Itemgroup class
class Itemgroup < ActiveRecord::Base
belongs_to :order
has_many :items, :dependent => :destroy
has_one :kind
accepts_nested_attributes_for :items, :kind
end
Order class
class Order < ActiveRecord::Base
has_many :itemgroups, :dependent => :destroy
has_many :items, :through => :itemgroups, :dependent => :destroy
has_many :kinds, :through => :itemgroups
accepts_nested_attributes_for :itemgroups, :allow_destroy => true
validates_associated :itemgroups, :items ,:kinds
end
The important part of the controller.
def update
#order = Order.find(params[:id])
if #order.update_attributes(params[:order])
flash[:notice] = 'Order was successfully edited.'
redirect_to(#order)
else
flash[:notice] = 'An error occured.'
render(:action => :edit)
end
end
Change
<% f.fields_for :itemgroups do |ff, i| %>
<% ff.fields_for :items do |fff| %>
<%= ff.text_field :text, :id => "textField", :disabled => true %>
<%= ff.text_field :price, :class => "priceField", :disabled => true %>
<%= fff.check_box :registered, :class => i %>
<% end %>
To EDITED
<% f.fields_for :itemgroups do |ff, i| %>
<%= ff.text_field :text, :id => "textField", :disabled => true %>
<%= ff.text_field :price, :class => "priceField", :disabled => true %>
<% ff.fields_for :items do |fff| %>
<%= fff.check_box :registered, :class => i %>
<% end %>
and check
Fixed the problem!
class Order < ActiveRecord::Base
has_many :itemgroups, :dependent => :destroy
has_many :items, :through => :itemgroups, :dependent => :destroy
has_many :kinds, :through => :itemgroups
accepts_nested_attributes_for :itemgroups, :allow_destroy => true
# validates_associated :itemgroups, :items ,:kinds
end
the validates_associated line was removed. Then it worked