0

好的,就这样吧。我不知道我是不是把事情复杂化了,或者我对 Rails 还是太陌生以至于我不了解基础知识。我在 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

然后我想要以下神奇的东西:

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

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

所以在写下来时,我可以看到我对这个模型的理解还有另一个差距。用户可以具有所有者、追随者或贡献者的角色或这三者的任意组合。

就实际代码而言,我在这里添加了我认为相关的部分:

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

关系模型的迁移是:

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

目前我收到诸如 project.users 之类的错误ActiveRecord::HasManyThroughAssociationNotFoundError: Could not find the association :relateable in model Project

我觉得我在这里太荒野了,无法真正得到我想要的东西,也许依靠神奇的铁轨来做更多的事情。任何关于最佳路径的指导将不胜感激。

提前致谢

史蒂夫

4

1 回答 1

2

Rails 可以做很多事情,但我认为您正试图让关系模型做得太多。每一种都是不同类型的关系,所以我想尽量保持这种关系。

将其拆分为单独的连接模型:

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

应该更接近你想要的。那么你确实可以做到

project.owner
project.followers
project.contributors

user.owned_projects
user.followed_projects
user.contributed_projects

这应该可以工作,或者让你非常接近。

我认为您的混淆来自于尝试建立多态关系,我认为这在这里是不可取的。AFAI grok,多态关系的用例是当您希望 1 个模型以相同的方式与任意数量的其他模型相关时。这里不是这种情况,因为您有 2 个模型,它们之间有 3 种不同类型的关系。

于 2011-06-20T01:03:16.587 回答