关于SO的第一篇文章,哇哦! RoR做到了:)在SO上有很多,甚至在RoR指南中也非常接近,但是我没有完全解决我想要做的事情。
我想对一种成分进行建模,其中每种成分也可能有一个有序的子成分列表 - (汇总)msyql表:
CREATE TABLE `ingredients`
id
name
CREATE TABLE `composite_ingredients`
parent_id
composite_id
sort_order int
CONSTRAINT `fk_one` FOREIGN KEY (`composite_id`) REFERENCES `ingredients` (`id`),
CONSTRAINT `fk_two` FOREIGN KEY (`parent_id`) REFERENCES `ingredients` (`id`)
这是我到目前为止的建模方式
class Ingredient < ActiveRecord::Base
attr_accessible :name
has_many :composites, :class_name=>"CompositeIngredient",
:foreign_key=>'parent_id'
has_many :sorted_composites, :through=>:composites,
:source=>:composite,
:class_name=>'Ingredient',
:order=>'sort_order asc'
class CompositeIngredient < ActiveRecord::Base
attr_accessible :sort_order
belongs_to :parent, :class_name=>'Ingredient',
:foreign_key=>'parent_id'
belongs_to :composite, :class_name=>'Ingredient',
:foreign_key=>'composite_id'
在rails控制台中进行测试时,我能够成功地解决这个问题:
a=Ingredient.includes(:sorted_composites).first
b=Ingredient.find_by_name 'corn'
a.sorted_composites<<b
这一切都运行正常 - 现在'a'将'b'与它正确关联(即:在连接表composite_ingredients中有一条记录。)但是,sort_order字段位于CompositeIngredient对象中,这些对象在a.composites(而我在a.sorted_composites中有实际的Ingredient对象。)当我向a.sorted_composites添加成分时,我想在插入连接表之前设置sort_order ...这有意义吗?我基本上想要做到这一点:
a.composites.create :parent_id=>a.id, composite_id=>b.id, sort_order=>a.sorted_composites.size
当我这样做时
a.sorted_composites << b
一旦我完成了这一点,我的has_many的:order选项将处理sortd_composites从数据库出来时的顺序 - 它将进入我需要连接的连接表。
谢谢大家!
修改 排序顺序的原因:复合成分出现顺序的隐含值 - 排在列表前面的那些是其父级的“丰富”组件。例如,如果父母成分X按此顺序复合Y和Z,则X在X中比Z更丰富。
修改 在玩了一些之后,这似乎是我能够提出的最有意义的解决方案:
class Ingredient < ActiveRecord::Base
attr_accessible :name
has_many :composites, :class_name=>"CompositeIngredient",
:foreign_key=>'parent_id',
**:before_add=>:before_composite_add**
...
def before_composite_add(new_composite)
new_composite.sort_order = self.sorted_composites.size
end
虽然是一个完整的RoR菜鸟,但我欢迎任何反馈/批评/建议。
答案 0 :(得分:0)
我已经发表评论澄清了,我觉得最好给你一些关于它如何运作的进一步想法:
您当前的设置依赖于
ingredients
,然后可以 使用composite_ingredients
联接模型关联。看起来像composite_ingredients
是一种自引用has_many :through
加入 模型,这可能有点僵硬(如果你想改变未来的结构怎么办)
为什么不用ancestry
gem将它们全部放在同一个模型中?这将允许您创建一个名为parent
的列,gem将填充该列。这将允许您在没有连接模型的情况下将任何成分与child
成分相关联:
@ingredient.children #-> all decendents of node
这将允许您取消连接模型,使您能够保留每个成分/子成分的sort_order
,而不是分成连接模型