【问题标题】:activerecord relations rails confusionactiverecord 关系消除了混乱
【发布时间】:2015-06-11 18:52:25
【问题描述】:

我想为饮料创建一个数据库。

每一种饮料都有很多成分,成分也有很多剂量。

因此,一种成分属于一种剂量,一种剂量属于鸡尾酒。

但是一旦我删除了一种饮料,我想删除相关的剂量而不是成分,因为它可以用于其他饮料。

目前我正在考虑像这样构建我的数据库。

rails g model drink name:string dose_id:references
rails g model dose cl:string ingredient_id:references
rails g model ingredient name:string

问题:

1) 这会满足我的需要还是我错过了什么?

2) 我需要鸡尾酒和成分之间的关​​系还是通过剂量来完成?如果是/否,为什么?

3) 除了将 FK 链接到 PK 之外,这 :references 是否还有其他作用?

4) :references 的命名是否重要,它如何检测要链接到的表?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    您可以阅读有关 rails 指南上的参考和迁移的更多信息,但这里有一些想法。

    1. 您似乎遗漏了什么。你希望drink 有很多ingredients。为dose 添加对drink 的引用意味着drink 只属于一个dose,因为它一次只能存储一个dose_id

    2. 您可能希望drinkingredients 之间存在多对多关系。一个drink 可以有多个ingredients。一种成分可以是许多drink 的一部分。 dose 实际上可以更成功地实现这一目标。

       rails g model drink name:string 
       rails g model dose cl:string ingredient:references drink:references
       rails g model ingredient name:string
      
    3. 它的行为应该像 SQL 中典型的 REFERENCES 约束。下面是一些不错的读物,但在 Rails 中,它也会在列上添加一个 btree 索引。

      一个。 http://www.postgresql.org/docs/9.4/static/ddl-constraints.html#DDL-CONSTRAINTS-FK

      b. How to use the keyword 'references' in MySQL?

    4. 生成迁移时,它会在引用关系中复数模型名称。

      rails g model dose ingredient:references 在架构中变成如下:

         ...
           add_index "doses", ["ingredient_id"], name: "index_doses_on_ingredient_id", using: :btree
           add_foreign_key "doses", "ingredients"
      

    【讨论】:

      【解决方案2】:

      我假设您使用 MySQL 和 Ruby 2。我建议您可以像这样构建您的模型:

      class Drink < ActiveRecord::Base
        has_many :doses, dependent: :destroy
        has_many :ingredients, through: :doses
      end
      
      class Dose < ActiveRecord::Base
        belongs_to :drink
        belongs_to :ingredient
      end
      
      class Ingredient < ActiveRecord::Base
        has_many :doses, dependent: :restrict
        has_many :drinks, through: :doses
      end
      

      Rails 中的关系遵循一些约定:

      • 表名是复数形式
      • 型号名称为单数形式
      • 外键命名为:othertable_id
      • 拥有belongs_to 关系的模型还包含外键(在您的情况下,这将是:drink_id:ingredient_id)。
      • :through 语句会为您生成 SQL 中的连接语句,因此您可以说 my_drink.ingredientsmy_ingredient.drinks
      • 删除饮料后,dependent: :destroy 将破坏您的 :doses,但不会破坏与之关联的 ingredients
      • dependent: :restrict 将拒绝删除仍被一剂或多剂使用的成分

      我总是为连接表使用一个额外的模型(你可以跳过它,rails 会为你做魔法)。但最大的优势是,您可以将额外的属性存储到该模型中,例如数量、单位……而且在您的 ruby​​ 代码中也很清楚,关系来自哪里。

      这些模型未经测试,我不能 100% 确定 :through 语法是否正确。但你应该明白了。

      【讨论】:

      • 谢谢你,这很有见地!
      • 不客气,如果您还需要什么,请告诉我。
      猜你喜欢
      • 2011-07-26
      • 2016-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-16
      • 2012-01-14
      • 1970-01-01
      • 2012-02-20
      相关资源
      最近更新 更多