我正在做我的第一个rails(3)应用程序。
协会没有意义。首先,即使是导轨也没有 真的解释了他们做了什么,他们只是解释了如何使用它们。 从我收集的内容来看,协会会做两件事:
a) Allow ActiveRecord to optimize the structure of the database.
b) Allow ActiveRecord to offer an alternate ruby syntax for
joins and the like (SQL queries). I want this.
我正在尝试理解关联,以及如何正确使用它们。基于 在下面的例子中,似乎协会被“打破”或至少 文档是。
考虑我的应用程序的一个简单版本。修改单词列表的老师 学习。
此讨论共有3个相关表格。为清楚起见,我很简单 包括annotate(1)工具对表的定义,并删除 不必要的字段/列。
词汇表管理表:
Table name: wordlist_mgmnt_records
id :integer not null, primary key
byline_id :integer(8) not null
将单词映射到单词列表的表格:
Table name: wordlists
wordlist_mgmnt_id :integer not null
word_id :integer not null
我们实际上并不关心这些词语本身。但我们关心 最后一张表,bylines:
Table name: bylines
id :integer(8) not null, primary key
teacher_id :integer not null
comment :text not null
Bylines记录了谁,使用了什么工具,在哪里,何时,等等 主要用来解决发生的事情,所以我可以向用户解释一下 他们应该做(和/或修复他们的错误)。
教师可以一次修改一个或多个单词列表管理记录 (又名单个署名)。换句话说,单个改变可以更新多个 单词列表。
对于wordlist_mgmnt_records,关联将是:
has_many :bylines # the same byline id can exist
# in many wordlist_mgmnt_records
但是bylines的相应条目是什么?
The Beginning Rails 3(Carneiro等人)的书中说:
"Note: For has_one and has_many associations, adding a belongs_to
on the other side of the association is always recommended. The
rule of thumb is that the belongs_to declaration always goes in
the class with the foreign key."
[是的,我也看了一下在线导轨指南。没有 救命。 ]
对于bylines表/类,我真的想说吗?
belongs_to :wordlist_mgmnt_records
这真的没有意义。 bylines表基本上属于belongs_to 数据库中的每个表都带有bylines_id。我真的会说 属于所有人?不会在所有的中设置外键 其他表?这反过来会使更改变得更加昂贵(太多了 CPU周期)比我真正想要的。一些变化涉及很多表,其中一些表 他们非常大。我在正常使用中获得速度,并愿意等待 使用行列进行清理/修复时查找没有外键的行。
这给我们带来了完整的循环。什么是协会真正做的铁路, 如何智能地使用它们?
只是使用关联,因为你似乎不是正确的 回答,但是如何获得添加的连接语法呢?
答案 0 :(得分:0)
我会尽力帮助你的混乱.......
byline 可以有多个wordlist_mgmnt_records
,因此定义has_many
似乎有意义。
我不确定我是否理解你在另一个方向上的困惑。由于您已定义属性wordlist_mgmnt_records.byline_id
,因此任何给定的wordlist_mgmnt_record
只能'拥有'(belongs_to)一个副行。你只是通过ruby定义了乌鸦脚(如果你喜欢数据库图表):
wordlist_msgmnt_records (many)>>----------(one) byline
或者用英文阅读:“一个byline可以有很多wordlist_mgmnts,而且许多单独的wordlist_mgmnt可以属于一个单行”
将belongs_to定义添加到wordlist_mgmnt模型不会影响查询的性能,只需让您执行以下操作:
@record = WordlistMgmntRecord.find(8)
@record_byline = @record.byline
此外,您还可以在以下表格上进行联接:
@records = WordlistMgmntRecord.joins(:byline).where({:byline => {:teacher_id => current_user.id}})
将执行此SQL:
SELECT wordlist_mgmnt_records.*
FROM wordlist_mgmnt_records
INNER JOIN bylines
ON wordlist_mgmnt_records.byline_id = bylines.id
WHERE bylines.teacher_id = 25
(假设current_user.id
返回25)
这是基于您当前的数据库设计。如果你发现有一种方法可以实现你想要的功能而不需要 byline_id
作为wordlist_mgmnt_records
表中的外键,那么你就可以修改你的模型以适应它。然而,这似乎是规范化数据库的外观,我不确定你会采用其他方式。