2017-02-05 7 views
0

私はrailstutorial.orgを完成した後にRailsアプリケーションを構築することによってコードを作成する方法を学んでおり、私は奇妙な問題を抱えています。メソッドがRailsで平均を返すことができないActiveRecord + Raw SQL

このアプリはランチを表示するように設計されています(従業員がランチを楽しんだかないかを投票することができます)。ランチはプロバイダに属し、プロバイダは料理に属します。

また、アプリはマルチテナントになる予定であるため、会社に関連付けられているメンバーモデルがあります。

昼食時の肯定的な好き嫌いの合計を昼食の票で割ったものが昼食のランチタイムです。

すべてランチレコードには、provider_id、member_id、およびlunchscore属性があります。

私の問題: 私は、特定のプロバイダに関連して、多くのランチに平均点心を取得しようとしています。これは私のProvider.rbモデルであるものである:

def average_member_lunch_score(member_id) 
    result = self.lunches.select("AVG(lunchscore) as average_lunchscore").where("date <= ? AND member_id = ? AND lunchscore > 0", Time.zone.now.beginning_of_day, member_id) 
    return result.average_lunchscore 
end 

私は、プロバイダ

arbys = Provider.find(id:2) 
arbys.average_member_lunch_score(2) 

に対してこれを実行すると、私は次のような結果を得る:私がしようとした場合、しかし、

NoMethodError: Lunch Load (0.1ms) SELECT AVG(lunchscore) as average_lunchscore FROM "lunches" WHERE "lunches"."provider_id" = ? AND (date <= '2017-02-05 05:00:00.000000' AND member_id = 2 AND lunchscore > 0) ORDER BY date ASC [["provider_id", 1]] 
undefined method `average_lunchscore' for #<ActiveRecord::AssociationRelation [#<Lunch id: nil>]> 

をaverage_member_lunch_scoreメソッドを手作業でやりとりしてSQLクエリ自体に書き込むために、私はそこでほとんどの方法を得ているようです:

arbys.lunches.select("AVG(lunchscore) as average_lunchscore").where("date <= ? AND member_id = ? AND lunchscore > 0", Time.zone.now.beginning_of_day, 2) 
    Lunch Load (0.1ms) SELECT AVG(lunchscore) as average_lunchscore FROM "lunches" WHERE "lunches"."provider_id" = ? AND (date <= '2017-02-05 05:00:00.000000' AND member_id = 2 AND lunchscore > 0) ORDER BY date ASC [["provider_id", 1]] 
+----+--------------------+ 
| id | average_lunchscore | 
+----+--------------------+ 
| | 0.8136429227338321 | 
+----+--------------------+ 
1 row in set 

returnメソッドについてはおそらく何かであると思われますが、メソッド自体が失敗する "id"の空白の値が返されているのに対し、クエリ自体は固まっているようです。

私の最終目標は、ビューには、この平均値を使用できるようにすることですので、私は次のように入力することができます。

<%= @provider.average_member_lunch_score(current_user.member_id) %> 

誰でもクエリが動作しますが、この方法が失敗した理由を説明するのに役立つことはできますか?また、selectステートメントにないのに、クエリが "id"カラムを返すのはなぜですか?

答えて

0

私は最終的に他人の助けを借りてこれに答えました。とてもアクティブなレコード平均法に建て使用すると、はるかに簡単にこれを作った、生のSQLにこれを破るに問題があったと思われるSQLで

def average_member_lunch_score(member_id) 
    return self.lunches.where("date <= ? AND member_id = ? AND lunchscore > 0", Time.zone.now.beginning_of_day, member_id).average("lunchscore") 
end 
0

、凝集がWHERE後に行われる(と働きます!)。集計値をフィルタするには、代わりにHAVINGを使用する必要があります。

lunches.select("AVG(lunchscore) as average_lunchscore"). 
    where("date <= ? AND member_id = ?", ...). 
    having("AVG(lunchscore) > 0") 
関連する問題