【问题标题】:rails3 and the proper way to use associationsrails3 和使用关联的正确方法
【发布时间】:2011-06-16 22:54:56
【问题描述】:

我正在做我的第一个 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

我们实际上并不关心单词本身。但我们确实关心 最后一张表,署名:

    Table name: bylines
    id           :integer(8)      not null, primary key
    teacher_id   :integer         not null
    comment      :text            not null

署名记录谁,使用什么工具,在哪里,何时等。署名是 主要用于解决发生的事情,所以我可以向用户解释什么 他们应该这样做(和/或修复他们的错误)。

教师可以一次修改一个或多个单词表管理记录 (又名单署名)。换句话说,一个更改可能会更新多个 单词列表。

对于 wordlist_mgmnt_records,关联为:

    has_many :bylines       # the same byline id can exist
                            # in many wordlist_mgmnt_records

但署名对应的条目是什么?

The Starting 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."

[ 是的,我也为此查看了在线 Rails 指南。没有 帮助。 ]

对于署名表/类,我真的想说吗?

    belongs_to :wordlist_mgmnt_records

这真的没有意义。署名表基本上是belongs_to 数据库中的每个表都有一个 bylines_id。所以我真的会说 属于他们所有人?那不是在所有的地方都设置了外键吗? 其他表?这反过来会使更改变得更加昂贵(太多 CPU 周期)比我真正想要的。一些变化影响了很多桌子,一些 它们非常大。我重视正常使用的速度,并愿意等待 使用署名进行清理/修复时查找没有外键的署名。

这给我们带来了完整的循环。协会在 Rails 中真正在做什么, 以及如何智能地使用它们?

仅仅因为你可以使用关联似乎并不正确 答案,但是如何获得添加的连接语法?

【问题讨论】:

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


    【解决方案1】:

    我会尽力帮助你解惑......

    一个署名可以有多个wordlist_mgmnt_records,所以在那里定义has_many似乎是有意义的。

    我不确定我是否理解您在另一个方向上的困惑。由于您已经定义了属性wordlist_mgmnt_records.byline_id,任何给定的wordlist_mgmnt_record 只能“拥有”(belong_to)一个署名。您只是通过 ruby​​ 定义鱼尾纹(如果您喜欢数据库图表):

    wordlist_msgmnt_records (many)>>----------(one) byline
    

    或者用英文阅读:“一个署名可以有多个 wordlist_mgmnt,而许多单独的 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)

    这是基于您当前的数据库设计。如果您发现有一种方法可以实现您想要的功能 wordlist_mgmnt_records 表中将byline_id 作为外键,那么您将修改您的模型以适应它。然而,这似乎是规范化数据库的外观,我不确定您会采取什么其他方式。

    【讨论】:

      猜你喜欢
      • 2023-03-10
      • 1970-01-01
      • 2018-04-19
      • 2011-03-31
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 2017-10-27
      • 2016-11-03
      相关资源
      最近更新 更多