0

我有一个Items 的数据库。每个项目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')))
4

3 回答 3

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
于 2013-03-18T12:34:22.543 回答
2

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

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

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

于 2013-03-18T11:48:21.083 回答
0

i think you should use thinking_sphinx gem for this.

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

end

to satisfy your requirements you can use has condition or where clause. you find out more on Click here

于 2013-03-18T23:09:27.383 回答