Question

How can i give an array as a placeholder without sqlite seeing as 1 value but several values that are in the array

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 ])

But i get this error:

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

Is there anyway to make it see 3 values in the array and not 1.

Was it helpful?

Solution

You need to add the splat operator * before you call your array:

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 ])

Small article about the splat operator: http://theplana.wordpress.com/2007/03/03/ruby-idioms-the-splat-operator/


Improvement for you: use .where() instead of .find()

First, the excellent guide about it: http://guides.rubyonrails.org/active_record_querying.html#conditions

Then, a little example to show the benefits of the 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

Different usages:

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

The same method, but using the where method (very nice for chain-scoping):

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

Keep in mind that you can chain scope with the .where method:

User.where(active: true).where('created_at < ?', Date.today-1.weeks).includes(:posts).where(posts: { name: "Name of a specific post" })
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top