5

基本的に、別のテーブルの値に応じてtrueまたはfalseを返すプロパティをモデルに定義しました。

私が欲しいのは、この条件を満たす結果のみを返すようにコントローラーでインデックスアクションを実行することです。

私はこれを試しました:

#What I've tried on my Controller:
def index
   @projects = Project.where(:is_available?)
end

#What I've on my Controller:
def index
   @projects = Project.all
end

#What I've on my Model:
def is_available?
   workers.count<2 ? true : false
end

ありがとう。

4

2 に答える 2

11

コードが機能しないのはなぜですか?

Project.where(:is_available?)

where メソッドでは、引数のハッシュまたは (SQL) 条件の文字列を渡す必要があります。ここでやろうとしていることは、メソッドが is_available? であるすべてのプロジェクトを選択することです? true を返します。問題は、メソッドis_available?が Ruby メソッド (モデルで定義されている) であることです。Ruby の関数なので、SQL 内で呼び出すことはできません。where メソッドは、Ruby コードではなく、SQL 条件を想定しています。

(コメントの@benzadoに感謝します)


問題を解決するには:

これはあなたが探しているもので、db レベルでのみ計算されます:

Project.joins(:workers)
       .select('projects.*')
       .group('projects.id')
       .having('COUNT(workers.*) > 2')

これにより、少なくとも 2 人のワーカーが関連付けられているすべてのプロジェクトが返されます。


これを改善するにはどうすればよいですか?

このクエリのスコープを作成して、どこでも簡単に使用できます。

#in your model
class Project < ActiveRecord::Base
  scope :having_more_than_x_workers, lambda do |workers_count|
    joins(:workers).select('projects.*').group('projects.id').having("COUNT(workers.*) > #{workers_count || 0}")
  end

end

たとえば、コントローラーで使用するには:

#in your controller
def index
   @projects = Project.having_more_than_x_workers(2)
end
于 2013-02-11T18:13:11.467 に答える
3

Rails クエリ メソッド ( などwhere) は、データベース クエリを作成することによって機能します。whereつまり、実際にデータ モデルに存在しない限り、属性を使用することはできません。そうしないと、データベースはそれを認識できず、フィルタリングを実行できません。

あなたの場合、Project「利用可能ですか?」を実行するクラスでメソッドを定義する必要があります。の代わりに独自のメソッドを使用できますwhere。次のように実行できます。

class Project < ActiveRecord::Base
  def self.available_projects
     where('workers_count > 2')
  end
end

クエリの書き方や名前付きスコープとして定義する方法の詳細については、 Yoshiji 氏の回答を参照してください。

于 2013-02-11T18:21:14.917 に答える