HABTM 2 个表 2 个不同的关系

发布于 2024-07-15 11:05:05 字数 246 浏览 2 评论 0原文

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

我有一个项目表,其中必须包含建议服务列表和已接受服务列表。

我知道我会在两侧使用 HABTM,并在其间使用 project_service_types 表。

当同一张表之间有两个不同的关系时,我不太清楚该怎么做。 我怀疑它使用 :join_table 和 :linked_forign_key,但我无法让它在我的应用程序中工作。

谢谢。

I have a Service Types table containing id and name of a couple of dozen services.

I have a Projects table that has to have a list of Proposed Services, and a list of Accepted Services.

I know that I would use HABTM on both sides with a project_service_types table in between.

I can't quite figure out what to do when I have 2 different relationships between the same table. I suspect it uses the :join_table and :associated_forign_key, but I can't get it to work in my app.

thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

孤单情人 2024-07-22 11:05:06

我用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

I solved it using 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
稚然 2024-07-22 11:05:06

虽然您可以使用 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

While you can solve this with habtm, what you're talking about is the use-case for has_many :through. You want to attach a bit of information along with the relationship. To do this you create a join model that represents the relationship.

In the end this allows you to treat your service proposal as a first-class "thing" in your domain. When the service is accepted you can just change the status. This also saves a join.

Migration

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

Models

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
昇り龍 2024-07-22 11:05:06

为此,您可能需要使用 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

更详细地解释了这一点。 希望这可以帮助!

For that you'd probably want to use has_many :through as in:

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

The many-to-many section here:

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

explains this in more detail. Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文