2013-08-22 34 views
0

我正在學習Ruby on Rails,以提高自己作爲開發人員,所以我開始重寫我的PHP網站來玩這個框架。
基本上該網站是一個源代碼聚集,因此,我有一個語言模型和源模型:Rails的find_by和模型的外鍵

class Language < ActiveRecord::Base 
    has_many :sources 
end 

class Source < ActiveRecord::Base 
    belongs_to :language 
end 

綁定的源表中的LANGUAGE_ID外鍵。
其中一個網站的主要途徑是:

get ':language_name/:source_name.html' => 'source#show' 

因此,例如:

/ruby/discover-if-a-number-is-prime.html 

在SourceController我已經宣佈:

class SourceController < ApplicationController 
    def show 
    language_name, source_name = params[:language_name], params[:source_name] 
    @language = Language.find_by_name(language_name) || not_found 
    @source = Source.find_by(name: source_name, language_id: @language.id) || not_found 
    end 
end 

有一個聰明的如何執行這兩個查詢?
也許像

@source = Source.find_by_name_and_language_name(source_name, language_name) || not_found 

對不起,如果這是一個愚蠢的問題,我在讀敏捷Web開發使用Rails 3.2太多,但在此之前,我想嘗試一點點。
感謝

回答

2

從馬立克回答的評論中提問,可以僅使用1個查詢使用joins

@source = Source 
    .joins(:language) 
    .where(languages: { name: language_name }) 
    .where(sources: { name: source_name }) 
    .first 

這將返回第一個匹配的sourcesource_name其語言相匹配language_name

+0

究竟是我在找什麼,我是一個表現瘋子,所以我更喜歡一個查詢的方式:)謝謝 –

1

如何:

@source = @language.sources.find_by_name(source_name) 

,或者,如果你想ActiveRecord::RecordNotFound如果適當源不存在待提高(最終導致渲染404頁):

@source = @language.sources.find_by_name!(source_name) 
+0

noob問題,是不是@ language.sources獲取*每*來源爲語言,然後過濾,因爲我有名字嗎? –

+1

不,「@ language.sources」返回「ActiveRecord :: Relation」實例。如果調用諸如'where','order'或'find_by_name'之類的方法,查詢將被適當地限定範圍。在這種情況下,您將得到類似於「SELECT來源。*從源WHERE來源.language_id = {{your_language_id}} AND sources.name = {{your_source_name}}''。 –

+0

@SimoneMargaritelli如果你仍然懷疑,你可以很容易地檢查它在rails控制檯中的工作情況 - 它以很好的形式顯示所有的SQL查詢。 –