I have a vendor model, a product model, and a vendor_product model. In my vendors form, I have used nested form to create vendor_products with attributes as vendor_id, product_id and copies.On creating a new vendor, it also creates a vendor_product. But for some reason, it does not stores the vendor_id and product_id in vendor_products table but only stores the copies
My associations are as follows
A vendor ->
has_many :vendor_products
has_many :products, through: :vendor_products
A product ->
has_many :vendor_products
has_many :vendors, through: :vendor_products
A vendor_product
belongs_to :vendor
belongs_to :product
Vendor.rb
class Vendor < ActiveRecord::Base
has_many :vendor_products
has_many :products, through: :vendor_products
accepts_nested_attributes_for :vendor_products, :products,
:allow_destroy => true
end
My vendors/_form.html.erb
<%= form_for(#vendor) do |f| %>
<% if #vendor.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#vendor.errors.count, "error") %> prohibited this
vendor from being saved:</h2>
<ul>
<% #vendor.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>
:
:
:
<%= f.fields_for :vendor_products do |vproducts| %>
<div class="field">
<%= vproducts.label :product %><br>
<%= collection_select(:product, :product_ids, Product.all, :id,
:product_name,
{:prompt => 'Please select', :multiple => true }) %>
</div>
<div class="field">
<%= vproducts.label :copies %><br>
<%= vproducts.number_field :copies %>
</div>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My vendors_controller.rb
class VendorsController < ApplicationController
before_action :set_vendor, only: [:show, :edit, :update, :destroy]
respond_to :json
def index
#vendors = Vendor.all.limit(20)
end
def show
end
def new
#vendor = Vendor.new
#vendor.products.build
#vendor.vendor_products.build
end
def edit
end
def create
#vendor = Vendor.new(vendor_params)
respond_to do |format|
if #vendor.save
format.html { redirect_to #vendor, notice: 'Vendor was successfully
created.' }
format.json { render :show, status: :created, location: #vendor }
else
format.html { render :new }
format.json { render json: #vendor.errors, status:
:unprocessable_entity }
end
end
end
def update
respond_to do |format|
if #vendor.update(vendor_params)
format.html { redirect_to #vendor, notice: 'Vendor was successfully
updated.' }
format.json { render :show, status: :ok, location: #vendor }
else
format.html { render :edit }
format.json { render json: #vendor.errors, status:
:unprocessable_entity }
end
end
end
private
def set_vendor
#vendor = Vendor.find(params[:id])
end
def vendor_params
params.require(:vendor).permit(:name, :email, :phone_no, :addressline1,
:addressline2, :landmark,
:city, :state, :country, :pincode, :latitude, :longitude, :status,
product_attributes: [:product_id, :product_name, :price ],
vendor_products: [:vendor_product_id, :vendor_id, :product_id,
:copies])
end
end
Now a vendor and VendorProduct is created but my vendor_product looks lik this
{"id":3,
"vendor_id":null,
"product_id":null,
"copies":4,
}
Can any one point out how to fix this. What am I doing wrong. Please bear in mind that I am a rails newbie.
change once vendor_products to vendor_products_attributes and look
In your view
<%= collection_select(:product, :product_ids, Product.all, :id,
:product_name,
{:prompt => 'Please select', :multiple => true }) %>
replace with
<%= vproducts.select :product_id, options_from_collection_for_select(Product.all, "id", "name"), prompt: "Select something" %>
Change this line:
<%= collection_select(:product, :product_ids, Product.all, :id,
:product_name,
{:prompt => 'Please select', :multiple => true }) %>
</div>
to
<%= collection_select(:product, :product_id, Product.all, :id,
:product_name,
{:prompt => 'Please select', :multiple => true }) %>
</div>
Related
I have a weird problem with "nested_form" in Rails. I made a model "evaluate" associated to other model "proyect", but when I try to show theres fields, on "proyects" form, just show fields from "proyects".
Here is my code:
Models:
proyect.erb
class Proyect < ActiveRecord::Base
belongs_to :user
has_many :vercions #I know is versions
has_many :evaluates #I know is evaluators
accepts_nested_attributes_for :evaluates, allow_destroy: true
validates :titulo,:presence => true,
:length => { :minimum => 3 }
validates :descripcion,:presence => true,
:length => { :minimum => 3 }
end
evaluate.erb
class Evaluate < ActiveRecord::Base
belongs_to :proyect
has_and_belongs_to_many :users
end
Controller
proyects_controller.erb
class ProyectsController < ApplicationController
before_action :set_proyect, only: [:show, :edit, :update, :destroy]
# GET /proyects
# GET /proyects.json
def index
if current_user.tipo == 'i'
#proyects = Proyect.where(:user_id => current_user.id)
else
#proyects = #Proyect.where(:id_user => current_user.id)
Proyect.all
end
end
# GET /proyects/1
# GET /proyects/1.json
def show
#vercion = Vercion.new
end
# GET /proyects/new
def new
#proyect = Proyect.new
#proyect.evaluates.build
end
# GET /proyects/1/edit
def edit
end
# POST /proyects
# POST /proyects.json
def create
#proyect = current_user.proyects.new(proyect_params)
respond_to do |format|
if #proyect.save
format.html { redirect_to #proyect, notice: 'Proyecto creado!.' }
format.json { render :show, status: :created, location: #proyect }
else
format.html { render :new }
format.json { render json: #proyect.errors, status: :unprocessable_entity }
end
# Llamamos al ActionMailer que creamos
Usermailer.bienvenido_email(current_user,#proyect).deliver
end
end
# PATCH/PUT /proyects/1
# PATCH/PUT /proyects/1.json
def update
respond_to do |format|
if #proyect.update(proyect_params)
format.html { redirect_to #proyect, notice: 'Proyect was successfully updated.' }
format.json { render :show, status: :ok, location: #proyect }
else
format.html { render :edit }
format.json { render json: #proyect.errors, status: :unprocessable_entity }
end
end
end
# DELETE /proyects/1
# DELETE /proyects/1.json
def destroy
#proyect.destroy
respond_to do |format|
format.html { redirect_to proyects_url, notice: 'Proyect was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_proyect
#proyect = Proyect.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def proyect_params
params.require(:proyect).permit(
:titulo, :descripcion,:evaluador, :id_user, :codigo, :user_assign,evaluates_attributes: [:id,:nombre, :prioridad, :_destroy, user_ids: [] ])
end
end
Views
_form.html.erb (Proyects)
<%= nested_form_for(#proyect) do |f| %>
<% if #proyect.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#proyect.errors.count, "error") %> prohibited this proyect from being saved:</h2>
<ul>
<% #proyect.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :titulo %><br>
<%= f.text_field :titulo %>
</div>
<div class="field">
<%= f.label :descripcion %><br>
<%= f.text_area :descripcion %>
</div>
<div class="field">
<%= f.hidden_field :id_user, :value => current_user.id %>
</div>
<!--Aqui añadi algo-->
<fieldset id="evaluates">
<%= f.fields_for :evaluates do |evaluates_form| %>
<div class="field">
<%= evaluates_form.label :status %><br>
<%= evaluates_form.text_field :status %>
</div>
<%= evaluates_form.link_to_remove "Eliminar esta tarea" %>
<% end %>
<p><%= f.link_to_add "Agregar una tarea", :evaluates %></p>
</fieldset>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
_evaluate_fields.html.erb
<div class="field">
<%= f.label :status, 'Nombre de la tarea' %><br>
<%= f.text_field :status %>
</div>
<div class="field">
<%= f.collection_check_boxes :user_ids, User.where(:tipo => 'e'), :id, :cedula %>
</div>
<%= f.link_to_remove "Eliminar Evaluador" %>
I am having issues understanding this.
What am I trying to accomplish?
Selected items in dropdown submitted to inventory.
Change the status of each item in a form in its own model.
Problem
I submit a form and the status of each item in the dropdown doesn't get submitted.
Any help would be appreciated.
Thanks in advance!
Form Code
<%= form_for(#inventory, html: {class: "form-horizontal"}) do |f| %>
<% if #inventory.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#inventory.errors.count, "error") %> prohibited this inventory from being saved:</h2>
<ul>
<% #inventory.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :tablet_id, "Tablet #", class: "col-md-2 control-label" %>
<div class="col-md-4">
<%= select("inventory", "tablet_id", Tablet.where("status = '1'").all.collect{ |t| [t.alias, t.id] }, {}, { class: "form-control"} ) %>
</div>
</div>
<%= f.fields_for :tablet do |t| %>
<%= t.hidden_field :status, value: 2 %>
<% end %>
<div class="form-group">
<%= f.label :chauffeur_id, "Chauffeur #", class: "col-md-2 control-label" %>
<div class="col-md-4">
<%= select("inventory", "chauffeur_id", Chauffeur.where("status = '1'").all.collect{ |t| [t.chaufNum, t.id] }, {}, { class: "form-control"} ) %>
</div>
</div>
<%= f.fields_for :chauffeur do |t| %>
<%= t.hidden_field :status, value: 2 %>
<% end %>
<div class="form-group">
<%= f.label :vehicle_id, "Vehicle #", class: "col-md-2 control-label" %>
<div class="col-md-4">
<%= select("inventory", "vehicle_id", Vehicle.where("status = '1'").all.collect{ |t| [t.vehNum, t.id] }, {}, { class: "form-control"} ) %>
</div>
</div>
<%= f.fields_for :vehicle do |t| %>
<%= t.hidden_field :status, value: 2 %>
<% end %>
<div class="form-group">
<div class="col-md-2 col-md-offset-2">
<%= f.submit class: "btn btn-sm btn-success" %>
</div>
</div>
<% end %>
Model (Inventory)
class Inventory < ActiveRecord::Base
belongs_to :tablet
belongs_to :chauffeur
belongs_to :vehicle
accepts_nested_attributes_for :tablet
accepts_nested_attributes_for :chauffeur
accepts_nested_attributes_for :vehicle
has_paper_trail
validates :tablet_id, :chauffeur_id, :vehicle_id, presence: true
validates :tablet_id, :chauffeur_id, :vehicle_id, uniqueness: { message: " is already checked out." }
end
Inventory Controller
class InventoriesController < ApplicationController
before_action :authenticate_user!
before_filter :set_paper_trail_whodunnit
before_action :set_inventory, only: [:show, :edit, :update, :destroy]
# GET /inventories
# GET /inventories.json
def index
#inventories = Inventory.all.paginate(:page => params[:page], :per_page => 15)
end
# GET /inventories/1
# GET /inventories/1.json
def show
#versions = PaperTrail::Version.order('created_at DESC')
end
# GET /inventories/new
def new
#inventory = Inventory.new
end
# GET /inventories/1/edit
def edit
end
def history
#versions = PaperTrail::Version.order('created_at DESC')
end
# POST /inventories
# POST /inventories.json
def create
# #inventory = Inventory.new(inventory_params)
render plain: params[:inventory].inspect
# respond_to do |format|
# if #inventory.save
# format.html { redirect_to #inventory, notice: 'Inventory was successfully created.' }
# format.json { render :show, status: :created, location: #inventory }
# else
# format.html { render :new }
# format.json { render json: #inventory.errors, status: :unprocessable_entity }
# end
# end
end
# PATCH/PUT /inventories/1
# PATCH/PUT /inventories/1.json
def update
respond_to do |format|
if #inventory.update(inventory_params)
format.html { redirect_to #inventory, notice: 'Inventory was successfully updated.' }
format.json { render :show, status: :ok, location: #inventory }
else
format.html { render :edit }
format.json { render json: #inventory.errors, status: :unprocessable_entity }
end
end
end
# DELETE /inventories/1
# DELETE /inventories/1.json
def destroy
#inventory.destroy
respond_to do |format|
format.html { redirect_to inventories_url, notice: 'Inventory was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_inventory
#inventory = Inventory.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def inventory_params
params.require(:inventory).permit(:tablet_id, :chauffeur_id, :vehicle_id, tablet_attributes: [:status => '2'], chauffeur_attributes: [:status => '2'], vehicle_attributes: [:status => '2'])
end
end
Clean all your nested attribute code. This is not what you want. So model like this:
class Inventory < ActiveRecord::Base
belongs_to :tablet
belongs_to :chauffeur
belongs_to :vehicle
has_paper_trail
validates :tablet_id, :chauffeur_id, :vehicle_id, presence: true
validates :tablet_id, :chauffeur_id, :vehicle_id, uniqueness: { message: " is already checked out." }
end
Now, what you want to use a rails callback so that when you create an inventory then you update the status of other things. This goes on your model too:
class Inventory < ActiveRecord::Base
...
after_create :update_status
protected
def update_status
self.tablet.update_attribute(:status, 2)
self.chauffeur.update_attribute(:status, 2)
self.vehicle.update_attribute(:status, 2)
end
end
Also remember to clean all your fields_for code and your strong parameters on your controller...you don't need the nested ones anymore.
I hope someone can help me.
I have a table with the name "location_location_relationships". If you create a new entry you can select two locations (predecessor and successor) which are from a "locaions" table. In addition you can select a tour. These are coming from table "tours". The locations selection is working. But the tours makes some problems. First I had nothing in the models everything worked but the selection wrote not the names but the ids in the "location_location_relationships" table. But I want the names in there. So I completed the models of "tours" and "location_location_relationships". In the selection there are the names of the tours now but if I press the Button "create" I get an error massage:
Tour(#96769428) expected, got String(#1848192)
and it shows me the error in the location_location_relationship_controller.rb in:
'def create
#location_location_relationship = LocationLocationRelationship.new(location_location_relationship_params)'
Has anyone an idea what I did wrong?
Thank you very much for your help in advance!
This is my location_location_relationships_form.html.erb where the collection_select is in:
<%= form_for(#location_location_relationship) do |f| %>
<% if #location_location_relationship.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#location_location_relationship.errors.count, "error") %> prohibited this location_location_relationship from being saved:</h2>
<ul>
<% #location_location_relationship.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label 'Von Ort' %><br />
<%= f.collection_select :predecessor_id, Location.all, :id, :name %>
</div>
<div class="field">
<%= f.label 'Zu Ort' %><br />
<%= f.collection_select :successor_id, Location.all, :id, :name %>
</div>
<div class="field">
<%= f.label 'Tour' %><br>
<%= f.collection_select :tour, Tour.all, :id, :name_of_tour, prompt: true %>
</div>
<div class="field">
<%= f.label 'Distanz' %><br>
<%= f.text_field :distance, type: "number", min:0 %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
My model of the location_location_relationships:
class LocationLocationRelationship < ActiveRecord::Base
belongs_to :successor, class_name: "Location"
belongs_to :predecessor, class_name: "Location"
validates :successor_id, presence: true
validates :predecessor_id, presence: true
belongs_to :tour
validates :tour, presence: true
validates :distance, :numericality => true
# validates :sequence, :numericality => {:only_integer => true}
# validates :binary_variable, :numericality => {:only_integer => true}
end
And my tours model:
class Tour < ActiveRecord::Base
#validates :tour, presence: true
has_many :location_location_relationships
def name_of_tour
name
end
end
And the location_location_relationships controller:
class LocationLocationRelationshipsController < ApplicationController
before_action :set_location_location_relationship, only: [:show, :edit, :update, :destroy]
# GET /location_location_relationships
# GET /location_location_relationships.json
def index
#location_location_relationships = LocationLocationRelationship.all
end
# GET /location_location_relationships/1
# GET /location_location_relationships/1.json
def show
end
# GET /location_location_relationships/new
def new
#location_location_relationship = LocationLocationRelationship.new
end
# GET /location_location_relationships/1/edit
def edit
end
# POST /location_location_relationships
# POST /location_location_relationships.json
def create
#location_location_relationship = LocationLocationRelationship.new(location_location_relationship_params)
respond_to do |format|
if #location_location_relationship.save
format.html { redirect_to #location_location_relationship, notice: 'Die Distanz wurde angelegt.' }
format.json { render :show, status: :created, location: #location_location_relationship }
else
format.html { render :new }
format.json { render json: #location_location_relationship.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /location_location_relationships/1
# PATCH/PUT /location_location_relationships/1.json
def update
respond_to do |format|
if #location_location_relationship.update(location_location_relationship_params)
format.html { redirect_to #location_location_relationship, notice: 'Die Distanz wurde aktualisiert.' }
format.json { render :show, status: :ok, location: #location_location_relationship }
else
format.html { render :edit }
format.json { render json: #location_location_relationship.errors, status: :unprocessable_entity }
end
end
end
# DELETE /location_location_relationships/1
# DELETE /location_location_relationships/1.json
def destroy
#location_location_relationship.destroy
respond_to do |format|
format.html { redirect_to location_location_relationships_url, notice: 'Die Distanz wurde gelöscht.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_location_location_relationship
#location_location_relationship = LocationLocationRelationship.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def location_location_relationship_params
params.require(:location_location_relationship).permit(:predecessor_id, :successor_id, :tour, :distance, :sequence, :binary_variable)
end
end
Tour(#96769428) expected, got String(#1848192)
You should change tour to tour_id
<div class="field">
<%= f.label 'Tour' %><br>
<%= f.collection_select :tour_id, Tour.all, :id, :name_of_tour, prompt: true %>
</div>
And also in location_location_relationship_params
def location_location_relationship_params
params.require(:location_location_relationship).permit(:predecessor_id, :successor_id, :tour_id, :distance, :sequence, :binary_variable)
end
I have trying to create a nested form with three models associated with through in one.
This is the schema:
These are the models:
../app/models/alimento.rb:
class Alimento < ActiveRecord::Base
attr_accessible :calorias, :nome, :refeicaos_attributes
validates :nome, :calorias, :presence => { :message => "nao pode ficar em branco" }
has_many :controles, :dependent => :destroy
has_many :refeicaos, through: :controles
has_many :diarios, through: :controles
accepts_nested_attributes_for :controles
end
../app/models/refeicao.rb:
class Refeicao < ActiveRecord::Base
attr_accessible :nome, :alimentos_attributes, :controles_attributes, :diario_attributes
validates :nome, :presence => { :message => "nao pode ficar em branco" }
has_many :controles, dependent: :destroy
has_many :alimentos, through: :controles
has_many :diarios, through: :controles
accepts_nested_attributes_for :controles
end
../app/models/diario.rb:
class Diario < ActiveRecord::Base
has_many :controles, dependent: :destroy
has_many :refeicaos, through: :controles
has_many :alimentos, through: :controles
accepts_nested_attributes_for :controles
attr_accessible :data, :controles_attributes, :refeicaos_attributes, :alimentos_attributes
end
../app/models/controle.rb:
class Controle < ActiveRecord::Base
belongs_to :alimento
belongs_to :refeicao
belongs_to :diario
attr_accessible :quantidade, :alimento_id, :refeicao_id, :diario_id
accepts_nested_attributes_for :alimento
accepts_nested_attributes_for :refeicao
accepts_nested_attributes_for :diario
end
I created many alimentos (food) and refeições (meals), now I need create a
daily control of diet through the model Diario that can contain many alimentos and refeições through the Controle (control) model.
../app/controllers/diarios_controller.rb:
class DiariosController < ApplicationController
# GET /diarios
# GET /diarios.json
def index
#diarios = Diario.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #diarios }
end
end
# GET /diarios/1
# GET /diarios/1.json
def show
#diario = Diario.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: #diario }
end
end
# GET /diarios/new
# GET /diarios/new.json
def new
#diario = Diario.new
end
# GET /diarios/1/edit
def edit
#diario = Diario.find(params[:id])
end
# POST /diarios
# POST /diarios.json
def create
#diario = Diario.new(params[:diario])
respond_to do |format|
if #diario.save
format.html { redirect_to #diario, notice: 'Diario was successfully created.' }
format.json { render json: #diario, status: :created, location: #diario }
else
format.html { render action: "new" }
format.json { render json: #diario.errors, status: :unprocessable_entity }
end
end
end
# PUT /diarios/1
# PUT /diarios/1.json
def update
#diario = Diario.find(params[:id])
respond_to do |format|
if #diario.update_attributes(params[:diario])
format.html { redirect_to #diario, notice: 'Diario was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: #diario.errors, status: :unprocessable_entity }
end
end
end
# DELETE /diarios/1
# DELETE /diarios/1.json
def destroy
#diario = Diario.find(params[:id])
#diario.destroy
respond_to do |format|
format.html { redirect_to diarios_url }
format.json { head :no_content }
end
end
end
I'm trying to do the "Nested Model Form (revised)" example.
Views:
../app/views/diarios/new.html.erb:
<%= form_for #diario do |f| %>
<div class="field">
<%= f.label :data %>
<%= f.date_select :data %>
<br>
</div>
<%= f.fields_for :refeicaos do |builder| %>
<%= render 'refeicao_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Adicionar Refeição", f, :refeicaos %>
</br>
</br>
<div class="actions">
<%= f.submit "Cadastrar Controle" %>
</div>
<% end %>
</br>
<%= link_to 'Voltar', root_path %>
../app/views/diarios/_refeicao_fields.html.erb:
<fieldset>
<strong>Refeição: </strong></br>
<%= f.label :nome, "Nome da Refeição", :style => 'margin-left: 5px;' %>
<%= collection_select(:refeicao, :id, Refeicao.order(:nome), :id, :nome) %>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remover Refeição" %>
</br>
</br>
<strong>Alimentos:</strong></br>
<%= f.fields_for :alimentos do |builder| %>
<%= render 'alimento_fields', f: builder %>
<% end %>
<%= link_to_add_fields "Adicionar Refeição", f, :alimentos %>
</fieldset>
../app/views/diarios/_alimento_fields.html.erb:
<fieldset>
<%= f.label :alimento, "Nome do Alimento:" %>
<%= collection_select(:alimento, :id, Alimento.order(:nome), :id, :nome) %>
<%= f.hidden_field :_destroy %>
<%= f.fields_for :controles do |builder| %>
<%= render 'controle_fields', f: builder %>
<% end %>
<%= link_to "Remover alimento", '#', class: "remove_fields" %></br>
</fieldset>
../app/views/diarios/_controle_fields.html.erb:
<fieldset>
<%= f.label :alimento, "Quantidade:", :style => 'margin-left: 42px;' %>
<%= f.number_field :quantidade, :style => 'width: 50px;' %>
</fieldset>
Custom helper created:
module ApplicationHelper
def link_to_add_fields(name, f, association)
new_object = f.object.send(association).klass.new
id = new_object.object_id
fields = f.fields_for(association, new_object, child_index: id) do |builder|
render(association.to_s.singularize + "_fields", f: builder)
end
link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")})
end
end
I get this error:
NoMethodError in Diarios#new
Showing D:/aplicacoes_indie/AppDieta/app/views/diarios/_refeicao_fields.html.erb where line #13 raised:
undefined method `alimentos' for nil:NilClass
Extracted source (around line #13):
10: <%= f.fields_for :alimentos do |builder| %>
11: <%= render 'alimento_fields', f: builder %>
12: <% end %>
13: <%= link_to_add_fields "Adicionar Refeição", f, :alimentos %>
14: </fieldset>
I've trying a lot of ways, but I can't solve this. The idea is: A Diario > with 1 or more refeicoes > with 1 or more alimentos and save each association through controle model.
Where am I wrong?
EDITED*
thanks for the answer, now the form appears
But should appear the number field 'quantidade' from controle below the select from alimento like this:
http://uploaddeimagens.com.br/images/000/123/917/full/model2.jpg?1385480010
../app/view/diarios/_alimento_fields.html.erb
<fieldset>
<%= f.label :alimento, "Nome do Alimento:" %>
<%= collection_select(:alimento, :id, Alimento.order(:nome), :id, :nome) %>
<%= f.hidden_field :_destroy %>
<%= f.fields_for :controles do |builder| %>
<%= render 'controle_fields', f: builder %>
<% end %>
<%= link_to "Remover alimento", '#', class: "remove_fields" %></br>
</fieldset>
../app/view/diarios/_controle_fields.html.erb
<fieldset>
<%= f.label :controle, "Quantidade:", :style => 'margin-left: 42px;' %>
<%= f.number_field :quantidade, :style => 'width: 50px;' %>
</fieldset>
One more thing, how can i mount the create action of Diario to get all the values of selects of alimentos and refeicaos and save each in controle model? Because I save and only create a Diario object with none association.
../app/controllers/diarios_controller.rb action create
def create
#diario = Diario.new(params[:diario])
respond_to do |format|
if #diario.save
format.html { redirect_to #diario, notice: 'Diario was successfully created.' }
format.json { render json: #diario, status: :created, location: #diario }
else
format.html { render action: "new" }
format.json { render json: #diario.errors, status: :unprocessable_entity }
end
end
end
I think these are the only accepts_nested_attributes_for statements that you should need:
class Diario < ActiveRecord::Base
accepts_nested_attributes_for :refeicaos
And:
class Refeicao < ActiveRecord::Base
accepts_nested_attributes_for :alimentos
Right now the <%= f.fields_for :refeicaos do |builder| %> statement is setting up the builder but builder.object is nil.
Edit - Changed field names to plural forms since this was a has_many relationship.
try:
class Alimento < ActiveRecord::Base
attr_accessible :calorias, :nome, :refeicaos_attributes
validates :nome, :calorias, :presence => { :message => "nao pode ficar em branco" }
has_many :controles, :dependent => :destroy
has_many :refeicaos, through: :controles
has_many :diarios, through: :controles
accepts_nested_attributes_for :controles
end
class Refeicao < ActiveRecord::Base
attr_accessible :nome, :alimentos_attributes, :controles_attributes, :diario_attributes
validates :nome, :presence => { :message => "nao pode ficar em branco" }
has_many :controles, dependent: :destroy
has_many :alimentos, through: :controles
has_many :diarios, through: :controles
accepts_nested_attributes_for :alimentos
end
class Diario < ActiveRecord::Base
has_many :controles, dependent: :destroy
has_many :refeicaos, through: :controles
has_many :alimentos, through: :controles
accepts_nested_attributes_for :refaicoas
attr_accessible :data, :controles_attributes, :refeicaos_attributes, :alimentos_attributes
end
class Controle < ActiveRecord::Base
belongs_to :alimento
belongs_to :refeicao
belongs_to :diario
attr_accessible :quantidade, :alimento_id, :refeicao_id, :diario_id
end
I've read through lots of posts here and still cant figure this one out.
I have a forum_post model and a links model. I want to nest the links form with the forum_post form but keep getting a Can't mass-assign protected attributes: links.
ForumPost Model
class ForumPost < ActiveRecord::Base
attr_accessible :content, :links_attributes
has_many :links, :as => :linkable, :dependent => :destroy
accepts_nested_attributes_for :links, :allow_destroy => true
end
Links Model
class Link < ActiveRecord::Base
attr_accessible :description, :image_url, :link_url, :linkable_id, :linkable_type, :title
belongs_to :linkable, :polymorphic => true
end
Forum_post View
<%= form_for(#forum_post) do |f| %>
<% if #forum_post.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#forum_post.errors.count, "error") %> prohibited this forum_post from being saved:</h2>
<ul>
<% #forum_post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :content %><br />
<%= f.text_area :content, :rows => 5 %>
</div>
<%= f.fields_for :link do |link| %>
<%= render :partial => 'links/link', :locals => { :f => link} %>
<% end%>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Link View Partial
<div class="field">
<%= f.label :link_url %><br />
<%= f.text_field :link_url, :id => "url_field" %>
</div>
<div id="link_preview">
</div>
ForumPosts Controller
class ForumPostsController < ApplicationController
def new
#forum_post = ForumPost.new
respond_to do |format|
format.html # new.html.erb
format.json { render json: #forum_post }
end
def create
#forum_post = ForumPost.new(params[:forum_post])
respond_to do |format|
if #forum_post.save
format.html { redirect_to #forum_post, notice: 'Forum post was successfully created.' }
format.json { render json: #forum_post, status: :created, location: #forum_post }
else
format.html { render action: "new" }
format.json { render json: #forum_post.errors, status: :unprocessable_entity }
end
end
end
Links Controller
class LinksController < ApplicationController
def find_linkable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
def index
#linkable = find_linkable
#links = #linkable.links
end
def create
#linkable = find_linkable
#link = #linkable.links.build(params[:link])
if #link.save
flash[:notice] = "Successfully saved link."
redirect_to :id => nil
else
render :action => 'new'
end
end
end
Well, according to your question the protected attributes that you can't mass-assign is :links.
Not sure how that happened, but have you tried attr_accessible :links?
As for the security implications, it is the reason github got hacked once https://gist.github.com/1978249, and I would highly discourage setting whitelist_attributes to false.