在此示例中,如何在rails中实现has_many:through关系 [英] How to implement has_many :through relationship in rails with this example
问题描述
我一直在寻找类似的问题,但是我仍然不知道如何实现这种关系.我当然有三种模式:
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将是一个配方(脚手架时出现典型错误),该配方可能具有一种或多种成分(已经在db上).因此,当我创建新的Recetum时,我需要创建新的Recetum,并在清单中为用户输入的每种成分插入一条记录.
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.
我现在需要有关视图和控制器的帮助,如何使用成分字段创建用于recetum的表单,更重要的是我必须修改recetum控制器.
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.
推荐答案
您有几个选择,主要取决于您在视图中要执行的操作.您是否要显示设定数量的max_ingredients
还是完全动态的?当然,动态案例对于用户来说看起来更好,但确实会使一些更复杂的代码成为现实.
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.
这是一个很好的RailsCast,它解释了如何通过JavaScript动态地做到这一点:
Here is a good RailsCast which explains how to do it dynamically via JavaScript:
http://railscasts.com/episodes/74-complex-forms-第2部分
不幸的是,并非所有人都启用了JavaScript,因此您可能需要考虑采用静态方式.
Unfortunately, not everyone runs with JavaScript enabled so you may want to consider doing it the static way.
首先,我认为您在Manifest
模型中不需要accepts_nested_attributes_for
.但是,我确实认为您在Recetum
模型中需要它.如果您要使用静态路线,则可能还需要设置一个reject_if
选项.
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
执行此操作后,您需要将manifests_attributes
添加到attr_accessible
.
Once you do this, you'll need to add manifests_attributes
to your attr_accessible
.
使用静态路由,您需要预先构建一些manifests
.在您的new
控制器中,您将需要以下内容:
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
在您的edit
和create
和update
的错误路径中,您可能想要:
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.
希望这足以让您入门.
这篇关于在此示例中,如何在rails中实现has_many:through关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!