1

我如何将数组作为占位符而不将 sqlite 视为 1 个值但数组中有几个值

value = Array.new    

value.push(broadcast_date_from)       
value.push(broadcast_date_to)    

puts value  #["a", "2006-01-02 00:00", "2006-01-02 23:59"]     

find(:all, :order => 'broadcast_date', :conditions => ['name LIKE ? and broadcast_date >= ? and  broadcast_date <= ?', name, @value ])

但我得到这个错误:

 wrong number of bind variables (1 for 3) in: name LIKE ? and broadcast_date >= ? and broadcast_date <= ?   

无论如何让它在数组中看到 3 个值而不是 1。

4

1 回答 1

1

您需要在调用数组之前添加 splat 运算符: *

values = ['condition for name']
values.push(broadcast_date_from)       
values.push(broadcast_date_to)

find(:all, :order => 'broadcast_date', :conditions => ['name LIKE ? and broadcast_date >= ? and  broadcast_date <= ?', *values ])

关于 splat 运算符的小文章:http: //theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/


为您改进:使用.where()代替.find()

首先,关于它的优秀指南:http: //guides.rubyonrails.org/active_record_querying.html#conditions

然后,一个小例子来展示 where 的好处:

class User < ActiveRecord::Base
  def get_posts(options = {})
    str_conditions = ['user_id = ?']
    args_conditions = [self.id]
    if options.has_key?(:active)
      str_conditions << 'active = ?'
      args_conditions << options[:active]
    end
    if options.has_key?(:after)
      str_conditions << 'created_at >= ?'
      args_conditions << options[:after]
    end
    if options.has_key?(:limit)
      Post.find(:conditions => [str_conditions.join(' OR '), *args_conditions], :limit => options[:limit])
    else
      Post.find(:conditions => [str_conditions.join(' OR '), *args_conditions])        
    end
  end

不同的用法:

user = User.first
user.get_posts(:active => true, :after => Date.today, :limit => 10)
user.get_posts

相同的方法,但使用 where 方法(非常适合链范围):

def get_posts(options = {})
  scope = self.posts
  scope = scope.where(active: options[:active]) if options.has_key?(:active)
  scope = scope.where('created_at >= ?', options[:after]) if options.has_key?(:after)
  scope = scope.limit(options[:limit]) if options.has_key?(:limit)

  return scope
end

请记住,您可以chain scope使用以下.where方法:

User.where(active: true).where('created_at < ?', Date.today-1.weeks).includes(:posts).where(posts: { name: "Name of a specific post" })
于 2013-12-19T18:52:49.317 回答