【问题标题】:rails 3 sqlite pass array in query via placeholderrails 3 sqlite 通过占位符在查询中传递数组
【发布时间】:2013-12-19 18:07:10
【问题描述】:

我怎样才能将数组作为占位符而不用 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 个。

【问题讨论】:

    标签: ruby-on-rails sqlite placeholder bind-variables


    【解决方案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
    

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

    User.where(active: true).where('created_at < ?', Date.today-1.weeks).includes(:posts).where(posts: { name: "Name of a specific post" })
    

    【讨论】:

    • 啊,谢谢@mamesaye,但如果我能给你一个提示,请使用.where 方法从数据库中查找对象,它在各个方面都好得多。如果您需要,我可以提供一些使用示例
    • 我刚刚更新了我的答案@mamesaye -- 希望对您有所帮助;;)
    猜你喜欢
    • 1970-01-01
    • 2013-08-23
    • 2011-03-19
    • 2012-12-14
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多