2016-04-29 1 views
2

現在Ruby on Railsで動作するウェブサイトを作成しています。私は、私は2人の異なる属性名を持っていること、2つのテーブル料金場所に参加しようとしたとき、私はいくつかの問題に直面しています。Ruby on Railsコントローラで異なる属性名を持つ2つの異なるテーブルを手動で結合する方法

料金:id rater_id rateable_id(このテーブルではさらにいくつかの属性)

場所:id title body user_id(このテーブルではさらにいくつかの属性)

ここでは、私がしようとしていますクエリですSQLで行うこと。

SELECT * 
FROM rates, locations 
WHERE rates.rater_id = locations.user_id AND rates.rateable_id = locations.id 

私はrubyonrails.orgが提供する公式のアクティブレコードの文書を読んでいます。私はこれらをやってみましたが、うまくいきません。ここで私はapp\controllers\users_controller.rb

@join_rating = Rate.joins(:locations).where("rates.rateable_id = locations.id AND rates.rater_id = locations.id") 
@all_rating = @all_rating.where(rater_id: @user) 
@count_all_rating = @all_rating.count 

@join_ratingに移植しようとしているコードは、異なる名前の属性に参加しようとしてされています。

@all_rating、ユーザー

て評価された場所の総数を計算しようとしている、ユーザーIDに

@join_ratingを使用して、表示する場所フィルタリングしようとしているが、すべてが正しくセットアップされていることを仮定し、唯一のエラーは、私がしようとしているクエリにあります。ユーザーが@all_ratingを使って評価した場所を表示できるように、どのように文を書き直すべきですか?

ありがとうございました!

答えて

1

Aを呼び出しますいくつかの点:

RateクラスのステートメントをActiveRecordで開始すると、結果はのコレクションになることを意味します0オブジェクト。したがって、の位置を表示しようとする場合は、Locationクラスから開始する必要があります。 @locations_user_rated = Location.joins( 'インナー rates.rateable_id = locations.idの金利をJOIN')。ここで、( '率

。rater_id '=> @user)

そして、あなたのActiveRecordのアソシエーションが明確に定義されている場合、あなたは、単に行うことができます:

@locations_user_rated = Location.joins(:料金).whereを(' rates.rater_id '=> @user)

「明確に定義されている」とは、単に次のようなことをする必要があることを意味します。モデルの関係を正しく理解しているかどうかはわかりません。私はすべての場所が複数の料金を持っていると仮定し、location_idの代わりにRateモデルにrateable_idというフィールドがある理由は、:rateablepolymorphicにしたいからです。つまり、ratesテーブルにrateable_typeフィールドがある可能性があります。

class Location < ActiveRecord::Base 
    has_many :rates, as: :rateable 
end 

class Rate < ActiveRecord::Base 
    belongs_to :rateable, polymorphic: true 
end 

この多型がない場合、物事は実際に簡単であるべき、と私は非常にあなたがRailsのの規則に従うと、単にあなたのRateモデルの代わりに、rateable_idに関係フィールドlocation_idに名前を付けることをお勧めします。そして、あなたが行うことができます:

class Location < ActiveRecord::Base 
    has_many :rates 
end 

class Rate < ActiveRecord::Base 
    belongs_to :location 
end 

をまだあなたがフィールド名について納得していない場合、あなたは物事をカスタマイズして行うことができます。

class Location < ActiveRecord::Base 
    has_many :rates, foreign_key: :rateable_id 
end 

class Rate < ActiveRecord::Base 
    belongs_to :location, foreign_key: :rateable_id 
end 

をあなたは団体hereをカスタマイズする方法の詳細、およびhereを見つけることができます。

+0

ありがとうございます。それは完全に動作します。あなたはwhere句でタイプミスをしました。しかし、私はそれをキャッチすることができます。 –

+0

ありがとうございます。どんなタイプミスなのか教えてください。私は答えを更新できます。 – AmitA

+0

'( 'rates.rater_id' => @ user.id).where(" rates.rateable_id = locations.id AND rates.rater_id = locations.user_id ")' <<< user_id –

0

ActiveRecordのhas_many,belongs_to、およびhas_many through:の機能を活用することを強くお勧めします。

あなたはこれらのテーブルのそれぞれのモデルを設定した場合は、正しい関係で:

class User < ActiveRecord::Base 
    has_many :ratings, foreign_key: :rater_id 
    has_many :rated_locations, through: ratings, class_name: Location.name, source: :rater 
end 

class Rating < ActiveRecord::Base 
    belongs_to :rater, class_name: User.name 
    belongs_to :location 
end 

class Location < ActiveRecord::Base 
    has_many :ratings 
end 

次に、ユーザが評価したことlocaitonsにアクセスするために、あなただけの

user.rated_locations 
+0

このメソッドを調べます。私はモデルで定義されたものを持っていましたが、使い方は分かりません。ありがとうございました! –

+0

@ MelvinCh'ngあなたのコードベースでこのメソッドを使うことを強くお勧めします。 Ruby on Railsが開発者に提供する最も強力な機能の1つです。アプリのコードはかなり読みやすく、制御可能になります。このガイドはあなたが知る必要があるすべてを学ぶのに役立ちます:http://guides.rubyonrails.org/association_basics.html – BananaNeil

+0

私はこの方法を私がラティレートの宝石を使用しているように使用することはできません。それはモデルと矛盾します。私は試しましたが、それは私にもっと多くの問題をもたらしました。 –

関連する問題