2013-03-04 77 views
0

我是新來的鐵軌,並試圖準確理解如何做關聯,如果我做得正確。我已閱讀rails guide on associations並搜索了網絡並找到了一些資源,但我不確定。簡單軌道3協會 - has_many,belongs_to和has_and_belongs_to_many

你可以在這裏看到我的項目:majorfinder.com在我的應用程序將有專業,學校和職業。我希望能夠爲每個評論添加評論。由於我剛剛開始,我剛剛開始爲專業添加評論。

這裏是我的協會:

型號/ review.rb

belongs_to :user 
has_and_belongs_to_many :majors 

型號/ user.rb

has_many :reviews 

型號/ major.rb

has_and_belongs_to_many :reviews 

我第一個問題是,這是否看起來像創建協會的好方法?

我知道該怎麼做在大滿貫賽控制器簡單的關聯關係:

@reviews = Review.includes(:user) 

,並與我可以告訴檢討我的主要控制器:

<div class="row"> 
    <% @reviews.each do |review| %> 
    <div> 
     <h3><%= link_to review.review, 
     :controller => "reviews", :action => "show", :id => review.id %></h3> 
     <small>Posted on <%= review.created_at %> by 
     <a href="#"><%= review.user.profile_name %></a></small> 
    </div> 
    <% end %> 
</div> 

,但我不知道怎麼樣使這個連接到我正在看的特定專業。

我的評論數據庫模式有review(text),user_id(integer)和major_id(integer)。

最後一個問題是,如何在主要控制器顯示頁面內發佈與該特定主要連接的評論?

回答

1

首先,您確定要reviewsmajors之間的has_and_belongs_to_many關係嗎?我假設每次審查只適用於某一個特定專業(或學校/職業),如果是一對多的關係,則您需要使用has_manybelongs_to。其次,由於您最終還想將評論添加到其他模型,因此您可能希望將其設置爲polymorphic association,這樣可以讓您爲所有其他三種模型使用相同的review模型。要做到這一點你要改變你的協會如下:

# In review.rb 
belongs_to :reviewable, polymorphic: true 

# In major.rb (and later also in school.rb and career.rb) 
has_many :reviews, as: :reviewable 

你還需要改變你的評價模型,然後讓而不是有major_id屬性,它有一個reviewable_idinteger屬性和reviewable_typestring財產。

在如何你要顯示他們而言,你可能會想包括reviewuser模型時首先加載你的專業(假設你想顯示所有的評論,雖然你可能最終想要看分裂他們成頁,如果有很多人):

# In majors_controller.rb (or whatever it's named) 
def show 
    @major = Major.includes(:reviews => :user).find(params[:id]) 
    ... 
在您看來,您可以將用戶的 @majorreviews方法來訪問他們

然後(記住,協會也add a bunch of methods到模型上做它更容易使用它們)

# In /app/views/majors/show.html.erb 
<div class="row"> 
    <% @major.reviews.each do |review| %> 
    ... 
    <% end %> 
</div> 

,或者更方便,你可以使用一個部分(如果你想顯示在每個頁面上以同樣的方式評語列表),並使用快捷渲染的集合:

# /app/views/reviews/_review.html.erb 
<div> 
    <h3><%= link_to review.review, 
    :controller => "reviews", :action => "show", :id => review.id %></h3> 
    <small>Posted on <%= review.created_at %> by 
    <a href="#"><%= review.user.profile_name %></a></small> 
</div> 

# In /app/views/majors/show.html.erb 
<div class="row"> 
    <%= render @major.reviews %> 
</div> 
+0

非常感謝你Zaid!這非常有幫助!我遇到了一個錯誤:在MajorsController中的NoMethodError#顯示未定義的方法'包括'爲#,在我的majors_controller.rb文件中,雖然我有:def show @major = Major.find_by_slug(params [:id])。包括(:reviews =>:user)end – lflores 2013-03-05 13:57:48

+1

這是我的錯,'.includes()'應該放在'.find()'之前,所以'@major = Major.includes(:reviews =>:user) .find_by_slug(params [:id])'應該工作。 – 2013-03-05 22:07:13

+0

它呢,謝謝你! – lflores 2013-03-07 02:10:09

0

至於至於這些是否是適當的關聯,這一切都取決於你想要達到的目標以及這些關係在「真實」世界中的實際狀況。

從它看起來像,在你的應用程序中你有用戶,誰可以創建(或有)許多不同的評論,你有專業,其中每個專業可以有很多評論相關的,你有評論,其中每個單獨的評論都與許多不同的專業相關(即一篇評論可以寫幾個不同的專業)。

這是正確的嗎?如果是這樣,那麼你試圖創建的關聯似乎是合適的。

但是,我不確定你在那裏的執行情況。

評論屬於用戶,因此它具有user_id列是合適的,但它不應該有一個major_id列(否則您將每個評論限制爲僅屬於一個主要)。

取而代之的是專業和評論之間的關係是通過一個連接表(例如major_reviews)進行管理的,然後它會有major_id和review_id列。你有沒有創建這個連接表?

一旦您將關聯設置正確,您將有權訪問多個rails方法,以便在運行查詢時讓您的生活更輕鬆。

例如,爲了獲得給定用戶的所有評論,你可以做@user.reviews。同樣,要獲得相關專業的個人審查,你可以做@review.majors,或獲得一個給定的專業的所有評論,你可以做@major.reviews

您可以在Rails指南http://guides.rubyonrails.org/association_basics.html#the-has_and_belongs_to_many-association的第4.4.1節中看到@major@review可用方法的更多示例。

+0

我其實確實希望每個評論只涉及一個專業。這聽起來像我可能已經正確設置了它。謝謝!! – lflores 2013-03-05 02:25:31

+0

在這種情況下,has_and_belongs_to_many可能不合適,正如Zaid在下面提到的,使用has_many和belongs_to來更好地使用專業和評論之間的關係。您的數據庫模式已經爲此設置,但您需要在模型中進行更改。 – simonb83 2013-03-05 02:50:34