How to implement has_many :through relationship in rails with this example

旧时模样 提交于 2019-12-08 09:35:38

问题


i've been searching through similar questions but i still don't get how implement this relationship. I have of course three models :

class Recetum < ActiveRecord::Base
    attr_accessible :name, :desc, :duration, :prep, :photo, :topic_id
    has_many :manifests
    has_many :ingredients, :through => :manifests
end

class Ingredient < ActiveRecord::Base
  attr_accessible :kcal, :name, :use, :unity
  has_many :manifests
  has_many :recetum, :through => :manifests
end


class Manifest < ActiveRecord::Base
  attr_accessible :ingredient_id, :quantity, :receta_id
  belongs_to :recetum
  accepts_nested_attributes_for :ingredient
  belongs_to :ingredient
end

Recetum would be a recipe (typo when scaffolding), this recipe may have one or more ingredients (already on the db). So when i create a new Recetum, i need the new recetum to be created and one record inserted in manifest for each ingredient entered by the user.

I would need some help now with views and controllers, how do i create the form for recetum with fields for the ingredients and more important what do i have to modify recetum controller.

Any suggestions or help would be very much appreciated as this part is crucial for my project, thanks in advance.


回答1:


You have a couple options, and mainly they depend on what you want to do in your view. Do you want to display a set number of max_ingredients or do you want it to be completely dynamic? The dynamic case looks better for the user for sure, but it does make for some more complicated code.

Here is a good RailsCast which explains how to do it dynamically via JavaScript:

http://railscasts.com/episodes/74-complex-forms-part-2

Unfortunately, not everyone runs with JavaScript enabled so you may want to consider doing it the static way.

Firstly, I don't think you need accepts_nested_attributes_for in your Manifest model. However, I do think you need it in your Recetum model. If you're going the static route, you'll probably want to set a reject_if option too.

accepts_nested_attributes_for :manifests, reject_if: :all_blank

Once you do this, you'll need to add manifests_attributes to your attr_accessible.

With the static route, you'll need to prebuild some of the manifests. In your new controller you'll want something like this:

max_ingredients.times do
  @recetum.manifests.build
end

In your edit and the error paths of your create and update, you may want:

(max_ingredients - @recetum.manifests.count).times do
  @recetum.manifests.build
end

Finally, your view will need some way to set the ingredient. I'll assume a select box for now.

f.fields_for :manifests do |mf|
  mf.label :ingredient_id, "Ingredient"
  mf.collection_select :ingredient_id, Ingredient.all, :id, :name

You'll want to add some sort of formatting through a list or table probably.

Hopefully, that's enough to get you started.



来源:https://stackoverflow.com/questions/14309337/how-to-implement-has-many-through-relationship-in-rails-with-this-example

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!