【问题标题】:RoR define meaningful relations between two modelsRoR 定义了两个模型之间的有意义的关系
【发布时间】:2009-11-25 00:58:30
【问题描述】:

我想在 Rails 项目中定义多对多关系。赋予个体关系不同含义的最佳方式是什么?

+------------+        has many        +-------------+
|            | ---------------------> |             |
|   person   |                        |   project   |
|            | <--------------------- |             |
+------------+        has many        +-------------+

这个模型开始时很好,但对于我想要实现的目标来说还不够。一个人应该能够在一个项目中扮演不同的角色。例如电影里有演员、制片人、特效师……

解决方案应该...

  • 提供一种简单的方法来定义新的关系类型(“角色”)
  • 以一种很好的方式集成到 Rails 中
  • 尽可能快

最好的选择是什么?

【问题讨论】:

    标签: ruby-on-rails many-to-many has-many semantics


    【解决方案1】:

    处理这个问题的最好方法是创建一个丰富的连接表。

    即:

           |  has many =>  |        |  <= has many  |
    Person |               | Credit |               | Movie
           | <= belongs to |        | belongs to => |
    

    Person 和 Movie 与最初的示例相比没有太大变化。 Credit 包含的字段不仅仅是 person_id 和 movie_id。 Credit 的额外字段将是角色和角色。

    那么它只是一个有很多通过关系。但是,我们可以添加额外的关联来获得更多细节。以电影为例:

    class Person < ActiveRecord::Base
      has_many :credits
      has_many :movies, :through => :credits, :unique => true
      has_many :acting_credits, :class_name => "Credit",
        :condition => "role = 'Actor'"
      has_many :acting_projects, :class_name => "Movie",
        :through => :acting_credits
      has_many :writing_credits, :class_name => "Credit", 
        :condition => "role = 'Writer'"
      has_many :writing_projects, :class_name => "Movie",
        :through => :writing_credits
    
    end 
    
    class Credit < ActiveRecord::Base
      belongs_to :person
      belongs_to :movie
    end
    
    class Movie < ActiveRecord::Base
      has_many :credits
      has_many :people, :through => :credits, :unique => true
      has_many :acting_credits, :class_name => "Credit",
       :condition => "role = 'Actor'"
      has_many :actors, :class_name => "Person", :through => :acting_credits
      has_many :writing_credits, :class_name => "Credit", 
       :condition => "role = 'Writer'"
      has_many :writers, :class_name => "Person", :through => :writing_credits
    end
    

    所有这些额外的关联。以下每一项都只是一个 SQL 查询:

    @movie.actors  # => People who acted in @movie
    @movie.writers # => People who wrote the script for @movie
    
    @person.movies # => All Movies @person was involved with
    @person.acting_projects # => All Movies that @person acted in
    

    【讨论】:

    • 天哪,一切都好! rails 几乎每天都让我感到惊讶......(我对它很陌生)感谢您的出色回答,正是我想要的!
    • 在电影类中,您的意思是“has_many :people, :through => :credits”而不是“has_many :people, :through => :jobs”,对吗?
    • 是的,我把它写成工作,然后意识到学分更有意义。所以我改变了它,一定错过了。很抱歉造成混乱。
    【解决方案2】:

    人员、项目和角色之间的关系应该是一张自己的表格。创建一个包含一个人、一个项目以及该人在该项目中的角色的 Assignment 类。然后是人has_many :projects, :through =&gt; :assignments

    【讨论】:

    • 感谢您的回答!你有一些流行语给我,以便我可以阅读更多有关该主题的信息吗?太好了,我对这一切仍然很不安全。
    • 我建议阅读 Rails 协会指南:guides.rubyonrails.org/association_basics.html
    猜你喜欢
    • 2019-05-07
    • 1970-01-01
    • 2020-10-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多