Rails 3、has_many :through 和 :polymorphic - 我需要这样做吗?
好的,就这样吧。我不知道我是否让事情变得过于复杂,或者我是否对 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 之类的错误在模型项目
中,
我觉得自己太身处荒野,无法真正得到我想要的东西,也许依靠神奇的轨道可以做更多的事情。任何关于最佳路径的指导将不胜感激。
预先感谢
史蒂夫
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. What I want in sudo code is this:
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
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Rails 可以做很多事情,但我认为你试图让关系模型做太多事情。每一种关系都是不同类型的,所以我想尽量保持这种关系。
将其拆分为单独的连接模型:
应该更接近您想要的。然后你确实可以这样做
,
这应该可以工作,或者让你非常接近。
我认为你的混淆来自于试图建立多态关系,我认为这在这里是不可取的。 AFAI grok,多态关系的用例是当您希望 1 个模型以相同的方式与任意数量的其他模型相关时。这里的情况并非如此,因为您有 2 个模型,它们之间有 3 种不同类型的关系。
Rails can do alot, but I think instead you're trying to make the Relationship model do too much. Each of those are a different kind of relationship, so I think try to keep them so.
Split that up into separate join models:
Should be a lot closer to what you want. You can then indeed do
and
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. That's not the case here, as you have 2 models with 3 different types of relationships between them.