Rails Rails 中的参数传递问题

runup · 2016年03月04日 · 最后由 runup 回复于 2016年03月04日 · 2328 次阅读

在看 railscast 中的Simple Search Form,参考该教程的代码:

projects/index.html.erb

<% form_tag projects_path, :method => 'get' do %>
  <p>
    <%= text_field_tag :search%>
    <%= submit_tag "Search" %>
  </p>
<% end %>

projects_controller.rb

def index
  @projects = Project.search(params[:search])
end

models/project.rb

def self.search(search)
  if search
    where ('name LIKE ?', "#{search}%")
  else
    all
  end
end

上面的教程可以按照预期执行,但是改写 project.rb 中代码

def self.search(search)
  if search
    #这句是改写的代码,这句话总是返回name like demo的语句。
    where('name LIKE ?', "demo")
  else
    all
  end
end

于是在 index.html.erb 中进行数据输入: 1、当输入一个特定的值的时候,比如“xx”,前端界面返回 select * from projects where name like "demo"的值,后台也能看到这个数据; 2、当输入空值的时候,前端界面还是返回如上的结果,我的理解当输入空值时候,应该返回 select * from projects;

如上提到的第二点是我想要问的问题,当 search 这个值是空值的时候我的预期是返回全部结果,而实际上返回了 select * from projects where name like "demo"这个结果,这是为何?

经楼下各位的提醒,解决了如上的问题,改动上面的代码,如下显示:

def index
  @projects = Project.search(params[:search])
  @type = params[:search].class
  @result = params[:search].nil?
end

经过演示知道如下结果:

@type #=>String
@result #=> false

查看了 api,并且在 irb 中经过演示如下:

"".class  #=>String
"".nil? #=> false

经过总结得出,Simple Search Form中的 else 后面的代码是不会被执行的,因为 search 的值永远返回的是 true,如下代码所示:

def self.search(search)
  if search
    where ('name LIKE ?', "#{search}%")
  else
    all
  end
end

因此对上面的代码进行改进,改进后的代码如下:

def self.search(search)
  where("name like ?", "#{search}%")
end

据猜测。。。输入空值实际上并不是空,你可以试着输出一下,search.class 因为很多情况下空有可能会是一个空字符串,所以判断的时候使用 search.empty?来做判断再试下。

输入空值的时候,params[:search] = '' ,所以直接用 if 判断返回 真,应该用 if search.blank? 或者 if search.empty? 来判断吧。

输入的空值不是 nil,而是“”。ruby 里这是 true 的,所以一直都执行 true 的代码

#1 楼 @taojay315 #2 楼 @raofeng #3 楼 @pathbox 谢谢各位提醒,已经在原帖里面把各位的建议进行了总结和代码演示。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号