2014-11-14 132 views
1

在Ruby on Rails中建立Has_Many through關係有各種參考,但關於如何處理關係的信息很少。有很多關係

我有以下變量一個用戶表:

t.string "email",     default: "", null: false 
t.string "encrypted_password",  default: "", null: false 
t.string "reset_password_token" 
t.datetime "reset_password_sent_at" 
t.datetime "remember_created_at" 
t.integer "sign_in_count",   default: 0, null: false 
t.datetime "current_sign_in_at" 
t.datetime "last_sign_in_at" 
t.string "current_sign_in_ip" 
t.string "last_sign_in_ip" 
t.string "confirmation_token" 
t.datetime "confirmed_at" 
t.datetime "confirmation_sent_at" 
t.string "unconfirmed_email" 
t.string "name" 
t.datetime "created_at" 
t.datetime "updated_at" 

然後,我有一個維基表:

t.string "title" 
t.datetime "published_at" 
t.datetime "created_at" 
t.datetime "updated_at" 
t.text  "body" 

而且,我有一個關係表中加入二:

t.integer "wiki_id" 
t.integer "user_id" 
t.boolean "creator_created" 
t.boolean "collaborator" 

關係類屬於其他類中的每一個:

belongs_to :users 
belongs_to :wikis 

其它兩個具有的has_many,通過代碼:

class User < ActiveRecord::Base 

    has_many :relationships 
    has_many :wikis, through: :relationships 

,反之亦然。

所以我的問題是,現在是什麼?我怎樣才能調用這些不同的類和它們的變量? user.wiki似乎不起作用,或user.relationship.wiki;即使relationship.created_creator也會提取錯誤信息!

特別是,我希望能夠找出用戶是否創建了一個wiki,以便該用戶可以編輯該wiki。我試着在用戶模式來創建一個方法是:

def creator?(wiki, user) 
    Relationship.where(wiki_id: wiki.id, user_id:user.id).creator_created 
end 

當我把它從一個政策文件,我得到的錯誤:

undefined method `creator_created' for #  <ActiveRecord::Relation::ActiveRecord_Relation_Relationship:0xbb19b84> 

誰能幫助我用我的has_many ,通過關係?我如何可以參考與用戶相關的wiki,或與兩者相關的creator_created字段?

謝謝!

回答

0

嘗試:

Relationship.where(wiki_id: wiki.id, user_id:user.id, creator_created: true) 
2

一個has_many關係返回一個集合。 Rails使用關聯名稱的複數形式來訪問相關對象。

要獲得用戶的維基,只是做:

user.wikis

要查找用戶是否創建了維基,你需要使用的關係:

user.wikis.where(relationships: {creator_created: true})

這展示瞭如何將範圍鏈接到關聯。

這可以通過添加一個範圍以Wiki模型進一步簡化:

scope :creator_created, -> { where(relationships: {creator_created: true}) }

,其允許:

user.wikis.creator_created

它可以是相當有幫助的添加.to_sql到端的表達式來查看生成的SQL語句。

這在很大程度上是覆蓋在滑軌指南Active Record Query Interface

EDIT

錯誤消息「NameError:未初始化的常數用戶::維基」的發生是由於在Relationship模型錯誤。 belongs_to協會用單數形式指定相關模型,所以他們更改爲:

belongs_to :user 
belongs_to :wiki 
+0

謝謝!不幸的是,我仍然收到錯誤「未初始化的常量User :: Wiki」。在Rails控制檯中,我爲用戶(調用'User.connection'建立連接):Class「得到錯誤」NoMethodError:undefined method'wikis'。有任何想法嗎? –

+0

我意識到我沒有指定一個用戶,但即使當我(User.last),我得到了錯誤「NameError:未初始化的常量User :: Wiki」 –

+1

你是如此接近:)請參閱我的編輯。 Rails中的整個複數/單數業務非常隨意。一旦你瞭解了慣例,它將成爲第二天性。 – zetetic

0

.where(...)返回模型對象的集合

def creator?(wiki, user) 
    # Raises error, as a model instance method (creator_created) is 
    # called on a collection: 
    Relationship.where(wiki_id: wiki.id, user_id:user.id).creator_created 
end 

在上面的代碼中,正在嘗試調用.creator_created上的收集Relationship對象(被發現假設對象匹配給.where(...)的條件)。

.creator_created是一種方法單個Relationship對象。無法在Relationship的集合上調用它。

修改給予creator?方法考慮到這會給:

def creator?(wiki, user) 
    relationships = Relationship.where(wiki_id: wiki.id, user_id: user.id) 
    if relationships.empty? 
    raise "No matching relationships found for wiki: '#{wiki}'" 
    end 
    # Use the first element from the relationships collection 
    relationship = relationships[0] 
    relationship.creator_created 
end 

然而,因爲方法的名字,我懷疑這可能是一個更可讀的解決方案:

def creator?(wiki, user) 
    user.relationships.find_by(wiki_id: wiki.id).creator_created 
end 

比較.find_by(...).where(...)find_by只返回單個模型實例(如果找到匹配項)。 .find_by docs.where docs都有示例代碼。

+0

嗨艾略特,謝謝你。 。 。我試過了你的最後一個def創造者?,它沒有傳遞任何東西。在rails控制檯中,我可以得到一個響應,但它表示結果爲'零',即使當我詢問關係記錄本身時,它也會顯示正確的wiki_id和user_id以及creator_created:true的記錄。 –