Undefined method when building association
Clash Royale CLAN TAG#URR8PPP
Undefined method when building association
I have two models as so:
Aceites belongs_to Warehouse
Warehouse has_many Aceites
These are my models:
class Warehouse < ApplicationRecord
has_many :aceites
validates :nombre, presence: true
end
class Aceite < ApplicationRecord
belongs_to :warehouse
validates :nombre, presence: true
validates :tipo, presence: true
validates :stock, presence: true
validates :warehouse_id, presence: true
end
Aceites controller (will put only crucial methods):
class AceitesController < ApplicationController
def new
@aceite = Aceite.new
end
def create
@aceite = Aceite.new(aceite_params)
@warehouse = @aceite.warehouses.build(aceite_params)
respond_to do |format|
if @aceite.save
format.html redirect_to aceites_url, notice: "Product added!"
format.js
else
format.js
end
end
end
private
def aceite_params
params.require(:aceite).permit(:nombre, :tipo, :stock, :warehouse_id)
end
end
The form:
<%= form_for(@aceite, remote: true, :html => class: 'form-horizontal', role: 'form' ) do |form| %>
<div class="form-group">
<%= form.label :nombre, class: 'form-control-label' %>
<%= form.text_field :nombre, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :tipo, class: 'form-control-label' %>
<%= form.text_field :tipo, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :stock, class: 'form-control-label' %>
<%= form.number_field :stock, class: 'form-control' %>
</div>
<div class="form-group">
<%= form.label :warehouse_id, class: 'form-control-label' %>
<%= form.collection_select(:warehouse_id, Warehouse.all, :id, :nombre) %>
</div>
<%= form.submit @aceite.new_record? ? "Add Product" : "Edit Product", class: "btn btn-primary btn-sm" %>
<% end %>
When I try to create a new Aceite
(a product) associated to a Warehouse
, I get the following error:
Aceite
Warehouse
Completed 500 Internal Server Error in 13ms (ActiveRecord: 0.0ms)
NoMethodError (undefined method `warehouses' for #<Aceite:0x00007f1141dfe2c0>
Can you please tell me what is wrong?
warehouses
Aceite
1 Answer
1
In your controller, you wrote:
@warehouse = @aceite.warehouses.build(aceite_params)
This line is the error. As you defined in the model that an Aceite
belongs_to a Warehouse
. But in the mentioned line you done the reverse. Your code reflects that a Warehouse
belongs_to Aceite
. So, the revised code would be:
Aceite
Warehouse
Warehouse
Aceite
You are trying to build a warehouse. Which is incorrect.
First, find the specific Warehouse (maybe you defined a nested route) :
@warehouse = Warehouse.find(params[:warehouse_id])
@aceite = @warehouse.aceites.new(aceite_params)
if @aceite.save
----- do something
end
If you don't define a nested route:
@aceite = Aceite.new(aceite_params) # in your aceite_params there is a warehouse_id, so the association will be done by rails
if @aceite.save
----- do something
end
Got it! It seems to work now, how can I access in the view for "Aceites" the warehouse name instead of ID? I have now aceite.warehouse_id. But I want to be able to show the name aceite.warehouse.name
– KronosL
Aug 13 at 22:45
get the specific
Aceite
object, like in the show page: @aceite = Aceite.find(params[:id])
, and in the view @aceite.warehouse.name
– Emu
Aug 14 at 4:17
Aceite
@aceite = Aceite.find(params[:id])
@aceite.warehouse.name
Yes for the show page that makes sense, but for index? I have now
@aceites = Aceite.all
and if i put @aceite = Aceite.find(params[:id])
it says cant find aceite withouth an ID.– KronosL
Aug 14 at 14:59
@aceites = Aceite.all
@aceite = Aceite.find(params[:id])
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
It is because there is no method
warehouses
defined onAceite
instance.– Jagdeep Singh
Aug 13 at 4:35