rails3和使用关联的正确方法

时间:2011-06-16 22:54:56

标签: ruby-on-rails-3 model-associations

我正在做我的第一个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周期)比我真正想要的。一些变化涉及很多表,其中一些表 他们非常大。我在正常使用中获得速度,并愿意等待 使用行列进行清理/修复时查找没有外键的行。

这给我们带来了完整的循环。什么是协会真正做的铁路, 如何智能地使用它们?

只是使用关联,因为你似乎不是正确的 回答,但是如何获得添加的连接语法呢?

1 个答案:

答案 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表中的外键,那么你就可以修改你的模型以适应它。然而,这似乎是规范化数据库的外观,我不确定你会采用其他方式。