简体   繁体   English

Rails 3,has_many:through和:polymorphic - 我应该这样做吗?

[英]Rails 3, has_many :through and :polymorphic - Should I need to do this?

Ok so here goes. 好的,所以这里。 I don't know if I'm over complicating things or if I'm just still so new to Rails that I don't understand the basics. 我不知道我是否过于复杂化,或者我是否仍然对Rails如此陌生,以至于我不了解基础知识。 What I want in sudo code is this: 我想在sudo代码中是这样的:

User
has_many projects as owner through relationship
has_many projects as contributor through relationship
has_many projects as follower through relationship

Project
has_one user as owner through relationship
has_many users as followers through relationship
has_many users as contributors through relationship

Relationship
belongs_to user
belongs_to project

Then I'm wanting to have the following magical things: 然后我想要有以下神奇的东西:

owner = Project.owner
followers = Project.followers
contributors = Project.contributors

projects = User.projects
myprojects = User.projects... (now I'm really not sure)
followedProjects = ...
contributingProjects = ...

So in writing that down I can see that there is another gap in my understanding of this model. 因此,在写下来时,我可以看到我对这个模型的理解存在另一个差距。 The users can have the role of owner, follower or contributor or any combination of all three. 用户可以拥有所有者,追随者或贡献者的角色或这三者的任意组合。

In terms of real code I have added here what I think is the relevant parts: 在实际代码方面,我在这里添加了我认为的相关部分:

class User < ActiveRecord::Base
  has_many :user_project_relationships, :as => :relateable, :class_name => "UserProjectRelationship"
  has_many :projects, :as => :owner, :through => :relateable, :class_name => "Project", :source_type => :owner
  has_many :projects, :as => :follower, :through => :relateable, :class_name => "Project", :source_type => :follower
  has_many :projects, :as => :contributor, :through => :relateable, :class_name => "Project", :source_type => :contributor
end

class Project < ActiveRecord::Base
  has_many :user_project_relationships, :as => :relateable, :class_name => "UserProjectRelationship"
  has_one :user, :as => :owner, :through => :relateable, :class_name => "User"
  has_many :users, :as => :followers, :through => :relateable, :source_type => :follower, :class_name => "User"
  has_many :users, :as => :contributors, :through => :relateable, :source_type => :contributor, :class_name => "User"
end

class UserProjectRelationship < ActiveRecord::Base
  belongs_to :user
  belongs_to :project, :polymorphic => true
end

The migration for the relationships model is: 关系模型的迁移是:

class CreateUserProjectRelationships < ActiveRecord::Migration
  def self.up
    create_table :user_project_relationships do |t|
      t.integer :relateable_id
      t.string :relateable_type
      t.integer :project_id
      t.timestamps
    end
    add_index :user_project_relationships, [:relateable_id, :relateable_type], :name => :relateable
    add_index :user_project_relationships, :project_id
  end

  def self.down
    drop_table :user_project_relationships
  end
end

Currently I get errors for things like project.users ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :relateable in model Project 目前我收到像project.users这样的东西的错误ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :relateable in model Project

I feel like I'm too in the wilderness here to really get what I want, and maybe relying on magical rails to do more than it does. 我觉得我在荒野中真的得到了我想要的东西,也许依靠神奇的铁轨来做更多的事情。 Any guidance on the best path would be greatly appreciated. 任何关于最佳路径的指导都将不胜感激。

Thanks in advance 提前致谢

Steve 史蒂夫

Rails can do alot, but I think instead you're trying to make the Relationship model do too much. Rails可以做很多事情,但我认为你试图让关系模型做得太多。 Each of those are a different kind of relationship, so I think try to keep them so. 每一种都是不同的关系,所以我想尽量保持这种关系。

Split that up into separate join models: 将其拆分为单独的连接模型:

class User < ActiveRecord::Base

  has_many :owned_projects, :class_name => "Project", :foreign_key => :owner_id

  has_many :projects_followers
  has_many :followed_projects, :class_name => "Project", :through => :projects_followers

  has_many :projects_contributors
  has_many :contributed_projects, :class_name => "Project", :through => :projects_contributors

end

class Project < ActiveRecord::Base
  belongs_to :owner

  has_many :projects_followers
  has_many :followers, :class_name => "User", :through => :projects_followers


  has_many :projects_contributors, :foreign_key => :contributor_id
  has_many :contributors, :class_name => "User", :through => :projects_contributors

end

class ProjectsFollowers < ActiveRecord::Base
  belongs_to :user
  belongs_to :project
end

class ProjectsContributors < ActiveRecord::Base
  belongs_to :user
  belongs_to :project
end

Should be a lot closer to what you want. 应该更接近你想要的。 You can then indeed do 那你可以做到

project.owner
project.followers
project.contributors

and

user.owned_projects
user.followed_projects
user.contributed_projects

That should either work, or get you pretty close. 这应该工作,或让你非常接近。

I think your mixup came from trying to make a polymorphic relationship, which I don't think is desireable here. 我认为你的混合来自于尝试建立多态关系,我认为这不是一个可取的关系。 AFAI grok, the use case for polymorphic relationships is when you want 1 Model to be related to Any number of other models in the same way . AFAI grok,多态关系的用例是当你希望1个Model以相同的方式与任意数量的其他模型相关时。 That's not the case here, as you have 2 models with 3 different types of relationships between them. 这不是这种情况,因为你有2个模型,它们之间有3种不同类型的关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM