2010-10-20 77 views
0

我正在Rails 3中開發一個小應用程序。在此應用程序中,用戶可以相互連接。我主要使用兩個表來存儲用戶數據和關係。我想用名字或姓氏搜索這些表來獲取用戶的聯繫人。使用Join in Rails進行搜索3

表ONE - 情景模式

在這個表,我存儲用戶的名字,姓氏和ID。

表TWO - 觸點

在此表中我存儲用戶的ID(PROFILE_ID),他被連接到(friend_id)的用戶的ID。

我正在使用以下查詢,但它沒有得到正確的結果。

Profile.find_by_sql("SELECT * FROM contacts 
       INNER JOIN profiles ON contacts.friend_id = profiles.id WHERE profiles.firstname = '#{@keyword}' OR profiles.lastname = '#{@keyword}'") 

是什麼問題,它是如何更有效?

回答

0

你可以只使用ActiveRecord的東西...

class Profile 
    has_many :contacts, :foreign_key => 'friend_id', :class_name => 'Contact' 
end 

class Contact 
end 

Profile.joins(:contacts).where({:contacts => {:firstname' => 'Cyril', :lastname => 'Mougel'}).all 
+0

我猜配置文件需要兩個:聯繫人和:朋友。 :聯繫人將以通常的方式定義has_many:聯繫人和:朋友將是你的:聯繫人 – Jean 2010-10-20 12:19:42

+0

這是可能的,但真的不是一個好的方式。添加了很多無用的方法 – shingara 2010-10-20 12:23:29

+0

@Shingara。我得到的錯誤:SQLite3 :: SQLException:沒有這樣的列:contacts.firstname:SELECT「profiles」。* FROM「profiles」WHERE(「contacts」。「firstname」='anders')AND(「contacts」。「lastname 「='anders') – 2010-10-20 16:57:17

1

三件事立場是「錯誤的」與您的查詢。

首先,您正在使用find_by_sql進行相對簡單的查詢。如果您要在整個應用程序中編寫像這樣的查詢,那麼您最好使用PHP。

其次是您將查詢參數傳遞到sql的方式。由於輸入未被轉義,這會使您對SQL注入攻擊敞開大門。

這兩個問題都可以使用內置的ActiveRecord方法解決。正如其他一些答案指出的那樣,這是一個非常簡單的重構。

我看到的第三個問題是沒有對外鍵使用標準的Rails命名約定。而不是Contacts.friend_id,它應該是Contacts.profile_id。這不是必需條件,但您的代碼越傳統,您需要在模型關係中使用的「黑客」越少。這條規則的唯一可接受的例外是如果您正在改造現有的數據庫模式,但聽起來不像這是您的情況。

我建議您查看RailsGuides以瞭解有關標準約定的更多信息。