0

好吧,所以在這裏。我不知道我是否過於複雜,或者如果我對Rails還是個新手,我不瞭解基礎知識。我想在須藤代碼是這樣的:Rails 3,has_many:through和:polymorphic - 我需要這樣做嗎?

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

我覺得我在這裏的荒野中真正得到我想要的東西,也許依靠神奇的導軌做比它更多的事情。任何關於最佳路徑的指導將不勝感激。

在此先感謝

史蒂夫

回答

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個模型與的任何數量的其他模型相關時。情況並非如此,因爲您有兩種模型,它們之間有三種不同類型的關係。

+0

感謝您的回覆。我認爲這聽起來像我想要的,但我想它感覺像在數據庫級別的重複。我來自多年的PHP/MySQL工作,我將使用單個連接表來處理來自雙方的關係。如:用戶 - 用戶2項目 - 項目。兩個關係成爲孤兒有沒有風險?這是下到應用程序執行?我在這裏添加兩個關係來服務多對多的每一方。如果一個人沒有另一個人被移走,你最終沒有遵循一個項目,但仍然被視爲項目方的追隨者。 – slarti42uk

+0

嘿,再次。遇到麻煩實施和測試它做我的期望。當我嘗試將用戶關聯到一個項目時出現此錯誤: 'project.project_followers << user ActiveRecord :: AssociationTypeMismatch:ProjectFollower(#215536​​2360)expected,got User(#2158321740)' – slarti42uk

+0

1)You're right關於孤兒 - 它也是由Rails處理的 - 你想添加:dependent =>:將keys刪除到projects_followers和projects_contributors。 2)projects_followers和projects_contributors在has_many_through關係中的完整性,如果您需要爲這些關係添加額外的鍵(多長時間以來,某人成爲貢獻者?他們做了多少貢獻等等),它們非常有用。但你也可以經常忽略它們。你得到這個錯誤的原因是你應該直接去追隨者協會:project.followers << user – MissingHandle