Rails:过滤索引页面和重新显示过滤器输入 [英] Rails: Filter index page and Re-display filter inputs

查看:58
本文介绍了Rails:过滤索引页面和重新显示过滤器输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不确定正确的 Rails 3 方法是什么.我想在索引视图的顶部设置过滤条件字段来过滤数据.

我下面的内容可用于过滤我的列表,但我还希望使用当前过滤器的内容重新填充过滤器字段,但我不知道该怎么做.我在下面使用的方法也不是实现此目的的正确"方法,因为它依赖于将空字符串传递给我认为的字段辅助方法之类的东西.

控制器:

 定义索引@animals = Animal.by_color(params[':color']).by_age(params[':age']).paginate(:page => params[:page])response_to do |格式|format.html # index.html.erbformat.xml { 渲染:xml =>@动物 }结尾

结束

查看:

列出动物

过滤:<%= form_for(:animal, :url => { :action => "index" }, :html => {:method => :get} ) do |f|%><div>颜色:<%= text_field'', ':color', :size =>10)%>年龄:<%= text_field('', ':age') %><%= f.submit "过滤器列表" %>

<%结束%><%= will_paginate %>...

我在我的模型中使用了范围方法,它工作得非常流畅.我只是对控制器params"方法和视图方法form_for"、text_field"如何相互映射感到模糊.关于如何重构它并在当前过滤列表时填充我的过滤器字段的任何想法?

解决方案!

控制器:

def 索引@search = Animal.new(params[:animal])@animals = Animal.by_color(@search.color).......

查看:

<%= form_for(@search, :url => { :action => "index" }, :html => {:method => :get} ) do |f|%><%= f.text_field(:color)

表单填充通过在我的控制器中创建@search 对象来工作(除了我的主要动物对象).然后使用 form_for 在它周围创建一个 for.

解决方案

您想要的是示例查询",它在控制器中的工作方式大致如下:

@filter = Animal.new(params[:filter])@animals = @filter.get_scope.paginate(:page => params[:page])

并且在控制器中,您可以对该示例记录执行 form_for,但我不知道任何现代 Rails 插件正是这样做的.当然应该有这样的东西,仔细看看.我敢打赌你可以在几个小时内写出类似的东西(只需将过滤器记录的属性散列抓取到范围的 :conditions 中,大致如此 - 未经测试):

 def get_scope# 删除所有 nill 属性non_default_attrs = self.attributesself.columns.each 做 |上校 |# 忽略具有默认值的列non_default_attrs.delete(col.name) 如果 non_default_attrs[col.name] == column.default# 忽略值为 nils 的列non_default_attrs.delete(col.name) 如果 non_default_attrs[col.name].nil?结尾其中(non_default_attrs.symbolize_keys)结尾

I am not sure what the proper Rails 3 way to do this is. I want to have filter criteria fields at the top of my index view that will filter the data.

What I have below works for filtering my list, but I also want the filter fields to be re-populated with what the current filter is, and I can't figure out how to do that. The method I got working below also doesn't feel like the "right" way to accomplish this, since it relies on things like passing empty string to the field helper methods in my view.

Controller:

 def index

@animals = Animal.by_color(params[':color']).by_age(params[':age']).paginate(:page => params[:page])

respond_to do |format|
  format.html # index.html.erb
  format.xml  { render :xml => @animals }
end

end

View:

<h1>Listing Animals</h1>

Filter By:
<%= form_for(:animal, :url => { :action => "index" }, :html => {:method => :get} ) do |f| %>
<div>
  Color: <%= text_field'', ':color', :size => 10 ) %>
  Age: <%= text_field('', ':age') %>
  <%= f.submit "Filter List" %>
</div>
<% end %>

<%= will_paginate %>

...

I am using the scope methods in my Model, which work very slick. I am just fuzzy about how the Controller "params" method and the View methods "form_for", "text_field" map to each other. Any ideas on how to refactor this and also get my filter fields populated when the list is currently filtered?

Solution!

Controller:

def index

@search = Animal.new(params[:animal])
@animals = Animal.by_color(@search.color)...

....

View:

<%= form_for(@search, :url => { :action => "index" }, :html => {:method => :get} ) do |f| %>
<%= f.text_field(:color)

The form population works by creating the @search object in my contorller (in addition to my main animals object). Then using form_for to create a for around it.

解决方案

What you want is a "query by example", which would work roughly like this in controller:

@filter = Animal.new(params[:filter])
@animals = @filter.get_scope.paginate(:page => params[:page])

and in the controller you could do a form_for on that example record, but I am not aware of any modern Rails plugins that do exactly that. There certainly should be something like this though, look thoroughly. I bet you could write something similar in a couple of hours though (just grab the attributes hash of your filter record into the :conditions of the scope, rougly like so - NOT TESTED THOUGH):

 def get_scope
   # remove all nill attrs
   non_default_attrs = self.attributes
   self.columns.each do | col |
     # Ignore columns that have default values
     non_default_attrs.delete(col.name) if non_default_attrs[col.name] == column.default
     # Ignore columns whose values are nils
     non_default_attrs.delete(col.name) if non_default_attrs[col.name].nil?
   end

   where(non_default_attrs.symbolize_keys)
 end

这篇关于Rails:过滤索引页面和重新显示过滤器输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆