【问题标题】:HABTM 2 tables 2 different relationshipsHABTM 2 表 2 种不同的关系
【发布时间】:2009-03-25 19:08:17
【问题描述】:

我有一个服务类型表,其中包含几十个服务的 ID 和名称。

我有一个 Projects 表,其中必须有一个 Proposed Services 列表和一个 Accepted Services 列表。

我知道我会在两边都使用 HABTM,中间有一个 project_service_types 表。

当我在同一张表之间有 2 种不同的关系时,我不知道该怎么办。我怀疑它使用 :join_table 和 :associated_forign_key,但我无法让它在我的应用程序中工作。

谢谢。

【问题讨论】:

    标签: ruby-on-rails has-and-belongs-to-many


    【解决方案1】:

    我使用 HABTM 解决了它...

    class ServiceType < ActiveRecord::Base
      has_and_belongs_to_many :accepted_projects, :class_name => "Project", :join_table => :projects_accepted_types
      has_and_belongs_to_many :proposed_projects, :class_name => "Project", :join_table => :projects_proposed_types
    end
    
    class Project < ActiveRecord::Base
      has_and_belongs_to_many :accepted_types, :class_name => "ServiceType", :join_table => :projects_accepted_types
      has_and_belongs_to_many :proposed_types, :class_name => "ServiceType", :join_table => :projects_proposed_types
    end
    

    【讨论】:

    • 这看起来可以解决问题;唯一需要注意的是,如果您以后可能希望将数据放在关联本身上(例如 ProjectsProposedTypes 模型中的注释字段),您将需要我的答案中详述的 has_many :through 选项。祝项目顺利!
    【解决方案2】:

    虽然您可以使用 habtm 解决这个问题,但您所说的是 has_many :through 的用例。您想在关系中附加一些信息。为此,您需要创建一个表示关系的连接模型。

    最终,这使您可以将您的服务提案视为您域中的一流“事物”。接受服务后,您只需更改状态即可。这也保存了一个连接。

    迁移

    create_table :project_services do |t|
      t.references :project
      t.references :service_type
      t.string :status
    end
    

    模型

    class ProjectService < ActiveRecord::Base
      belongs_to :project
      belongs_to :service
    end
    
    class Project < ActiveRecord::Base
      has_many :project_services
      has_many :accepted_services, :through => :project_services,
        :conditions => { :status => 'accepted' }
      has_many :proposed_services, :through => :proposed_services,
        :conditions => { :status => 'proposed' }
    end
    
    class Service < ActiveRecord::Base
      has_many :project_services
      has_many :accepted_projects, :through => :project_services,
        :conditions => { :status => 'accepted' }
      has_many :proposed_projects, :through => :proposed_services,
        :conditions => { :status => 'proposed' }
    end
    

    【讨论】:

      【解决方案3】:

      为此,您可能希望使用 has_many :through :

      class ProposedService < ActiveRecord::Base
          belongs_to :project
          belongs_to :service_type
      
      class AcceptedService < ActiveRecord::Base
          belongs_to :project
          belongs_to :service_type
      
      class Projects < ActiveRecord::Base
          has_many :proposed_services
          has_many :accepted_services
          has_many :service_types, :through => :proposed_services
          has_many :service_types, :through => :accepted_services
      
      class ServiceTypes < ActiveRecord::Base
          has_many :proposed_services
          has_many :accepted_services
          has_many :projects, :through => :proposed_services
          has_many :projects, :through => :accepted_services
      

      这里的多对多部分:

      http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html

      更详细地解释了这一点。希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-08
        相关资源
        最近更新 更多