Reputation: 5
I've a stock, and a calving model.
A stock (has an id, name, and a mother_id) can have carves through a calving, so I have this in my stock model.
has_many :stocks, through: :calvings
has_many :calvings
In Calving model i have:
has_many :calves, class_name: "Stock", foreign_key: "mother_id",
accepts_nested_attributes_for :calves
I have a form for creating Calving, where the user can:
-choose the stock_id (it will be the mother)
-add how many carves was born
-give a name for every carf (depending on the nr of carves born)
I would like to save this data, but when it creates the Stock record, it puts the carving.id into the stock.mother_id field, not the carving.stock_id.
How can i fix this?
And if it is possible, what should I do, to fill the form with the right data when I want to edit the record?
Upvotes: 0
Views: 249
Reputation: 76774
If you're creating records in a has_many :through
association, you first need to create the records for the join model, then pass the records through the "child" model
Here's how we do it:
Models
#app/models/stock.rb
Class Stock < ActiveRecord::Base
has_many :calvings, class_name: "Calving"
has_many :calves, class_name: "Calf", through: :calvings
accepts_nested_attributes_for :calving
#build relevant objects (DRYes up controller)
def self.build
stock = self.new
stock.calvings.build.build_calf
stock
end
end
#app/models/calving.rb
Class Calving < ActiveRecord::Base
belongs_to :stock
belongs_to :calf
accepts_nested_attributes_for :calf
end
#app/models/calf.rb
Class Calf < ActiveRecord::Base
has_many :calvings, class_name: "Calving"
has_many :stocks, class_name: "Stock", through: :calvings
end
stocks #needs to identify mother only
id | name | created_at | updated_at
calvings
id | stock_id | calf_id | extra | info | created_at | updated_at
calfs
id | name | extra | information | created_at | updated_at
Controllers
These models give you a structure where you'll have a join model (which holds the relation between stocks
and calves
, allowing you to populate them as required:
#app/controllers/stocks_controller.rb
def new
@stock = Stock.build
end
def create
@stock = Stock.new(stock_params)
@stock.save
end
private
def stock_params
parmas.require(:stock).permit(:name, calvings_attributes: [calf_attributes:[:info]]
end
Forms
Finally, you'll be able create the form as follows:
#app/views/stocks/new.html.erb
<%= form_for @stock do |f| %>
<%= f.name %>
<%= f.fields_for :calvings do |c| %>
<%= c.fields_for :calf do |calf| %>
<%= calf.text_field :info %>
<% end %>
<% end %>
<% end %>
Update
Rails, self-referential association on the User model to define friends/followers
Might be able to do it like this:
#app/models/stocks.rb
Class Stock < ActiveRecord::Base
has_many :calvings
has_many :calves, class_name: "Stock", through: :calvings
end
#app/models/calvings.rb
Class Calving < ActiveRecord::Base
belongs_to :mother, :class_name => "Stock", foreign_key: "mother_id"
end
I'm not actually sure about this to be honest -- needs more thought. Typically, you'd use a standard has_many :through
relationship for it. I'll email to get a call going - we need to fix this!!!
Upvotes: 1