忽略活动记录Rails 4中为null的参数

时间:2016-04-11 15:05:43

标签: ruby-on-rails ruby-on-rails-4 rails-activerecord

我创建了一个简单的网络表单,用户可以在其中输入一些搜索条件来查找场地,例如价格范围。当用户点击“查找”时,我使用活动记录来查询数据库。如果填写了所有字段,这一切都很有效。当一个或多个字段保持打开状态时出现问题,因此值为null。

如何在我的控制器中解决这个问题?我应该首先检查一个值是否为null并根据它创建一个查询?我可以想象我最终得到了许多不同的查询和大量的代码。必须有更快的方法来实现这一目标吗?

控制器:

def search
   @venues = Venue.where("price >= ? AND price <= ? AND romance = ? AND firstdate = ?", params[:minPrice], params[:maxPrice], params[:romance], params[:firstdate])
end

4 个答案:

答案 0 :(得分:11)

您可能希望过滤掉随请求一起发送的所有空白参数。

这是一个快速干燥的解决方案,用于过滤空白值,仅触发数据库的一个查询,并使用Rails&#39;来构建where子句。 ActiveRecord ORM。

正如@DanBrooking所指出的,这种方法可以防止SQL注入。 Rails 4.0+提供了强大的参数。&#34;您应该使用该功能。

class VenuesController < ActiveRecord::Base

  def search
    # Pass a hash to your query
    @venues = Venue.where(search_params)
  end

  private

    def search_params
      params.
        # Optionally, whitelist your search parameters with permit
        permit(:min_price, :max_price, :romance, :first_date).
        # Delete any passed params that are nil or empty string
        delete_if {|key, value| value.blank? }
    end
end

答案 1 :(得分:1)

尝试以下代码,它将忽略那些不存在的参数

conditions = []
conditions << "price >= '#{params[:minPrice]}'" if params[:minPrice].present?
conditions << "price <= '#{params[:maxPrice]}'" if params[:maxPrice].present?
conditions << "romance = '#{params[:romance]}'" if params[:romance].present?
conditions << "firstdate = '#{params[:firstdate]}'" if params[:firstdate].present?

@venues = Venue.where(conditions.join(" AND "))

答案 2 :(得分:0)

我建议在Venue中制作方法

import bottle
from bottle import run, get, post, request, route, error, default_app
from socket import * 
import serial
host = ''
port = 7000

@route('/system')
def login():
    return '''

    <form action="/system" method="post" class="pure-form pure-form-aligned">
        <button type="submit" class="pure-button pure-button-primary">Connect</button>
    </form>

    '''

@route('/system', method='POST')
def syson():
    our_socket = socket(AF_INET, SOCK_STREAM)
    our_socket.connect((host, port))
    message = "go"
    our_socket.send(bytes(message,'UTF-8'))
    reply = our_socket.recv(1024)
    message = "go"
    our_socket.send(bytes(message,'UTF-8'))
    reply = our_socket.recv(1024)
    return bottle.redirect("/system")

run(host='localhost', port=8000)

并在您的控制器中使用它 def self.find_by_price(min_price, max_price) if min_price && max_price where("price between ? and ?", min_price, max_price) else all end end def self.find_by_romance(romance) if romance where("romance = ?", romance) else all end end def self.find_by_firstdate(firstdate) if firstdate where("firstdate = ?", firstdate) else all end end

答案 3 :(得分:0)

这个问题的另一个解决方案,我认为更优雅,是使用具有条件的范围。 你可以做点什么

class Venue < ActiveRecord::Base   
  scope :romance, ->(genre) { where("romance = ?", genre) if genre.present? } 
end

然后你可以链接那些,如果没有参数,它将作为AND工作,然后它不是链的一部分。

http://guides.rubyonrails.org/active_record_querying.html#scopes