如何在带有activerecord的rails中正确编写复杂的where子句?

时间:2013-03-18 11:33:17

标签: ruby-on-rails-3 activerecord where-clause

我有一个Item的数据库。每个项belongs_to一个User。每个项目都有visibilitystatus字段。为了便于搜索,项目必须满足以下规则:

status must be :available
  AND 
  (visibility must be :everyone
    OR
    (visibility must be :friends AND user_id must be in current_user.friends)
  )

换句话说,您会看到所有可用的和公开的项目,并且您会看到朋友的“私人”项目。

如何检索符合此条件的项目?


我尝试了以下内容:

class Item < ActiveRecord::Base

  belongs_to :user
  attr_accessible :description, :photo, :title, :user_id, :visibility

  #...

  scope :searchable, lambda { |user|
    where('status IN ? AND (visibility IN ? OR (visibility IN ? AND user_id IN ?))',
          [:available, :lent],
          [:everyone],
          [:friends],
          user.friends)
  }
end

在我的控制器中:

@items = Item.searchable(current_user)

但我有一个错误:

IN生成条款

没有任何措施
ActiveRecord::StatementInvalid in Items#search

SQLite3::SQLException: near ",": syntax error: SELECT "items".* FROM "items"  WHERE (status IN 'available','lent' AND (visibility IN 'everyone' OR (visibility IN 'friends' AND user_id IN 'foo')))

3 个答案:

答案 0 :(得分:4)

我个人更喜欢使用lambda在范围内声明一个类方法。我觉得它更容易阅读。另外,设置默认值更容易。

def self.with_status(statuses)
  where(status: statuses)
end

def self.visible_to_friends_of(user)
  where('visibility = ? OR (visibility = ? AND user_id IN (?))',
    'everyone',
    'friends',
    user.friends
  )
end

def self.searchable(user)
  with_status([:available, :lent]).visible_to_friends_of(user)
end

答案 1 :(得分:2)

好吧,我不知道你必须把自己放在?周围(正如你所说的@MurifoX)

scope :searchable, lambda { |user|
    where('status IN (?) AND (visibility IN (?) OR (visibility IN (?) AND user_id IN (?)))',
          [:available, :lent],
          [:everyone],
          [:friends],
          user.friends)
}

如果有更好的方法来实现这种行为,我仍然是开放的。

答案 2 :(得分:0)

我认为你应该使用thinking_sphinx gem。

define_index do
indexes title
indexes description
indexes uploads.file_file_name, :as => :upload_file_name
indexes uploads.file_content_type, :as => :upload_file_content_type

has :id
has price
has user_id
has created_at
has purchase_count
has images.photo_file_size
has tags.id, :as => :tag_id, :facet => true
has tags.parent_id, :as => :tag_parent_id, :facet => true
has "state='active'", :as => :active, :type => :boolean, :facet => true
has "count(images.id) > 0", :as => :has_image, :type => :boolean
has "sum(uploads.file_file_size)", :as => :total_size, :type => :integer

where "state in ('active', 'pending')"

set_property :delta => true
set_property :morphology => 'stem_en'
set_property :min_prefix_len => 3
set_property :enable_star    => true

为了满足您的要求,您可以使用条件或where子句。 您可以点击here

了解更多信息