如何制作可选:查找条件

时间:2010-06-30 14:30:00

标签: ruby-on-rails

你好我的脑子里有跟随斗争。我想要一个文本字段,其中的用法可以输入一些参数,这些参数将用作我的find方法中的:conditions哈希的过滤条件。

我创建了一个帮助器,带有一个选项并将哈希值合并到选项中:

在我的控制器中:

@bills = adminbill_filter(:limit=>params[:limit] || 50,:offset=>params[:offset] || 0, :conditions=>params[:options])

在我的帮手中:

  def link_to_with_current(text, link, condition, *args)
    options = args.first || {}
    options[:class] = condition ? 'current' : nil
    link_to text, link, options
  end

在我看来:

<%= text_field :filter ,:criteria, :class=>'roundRect',:id=>'name', :value=>12009%>
<%= button_to_with_filter 'Start Filter', 'index', :filter_condition=>true, :options=>{:id=>81}%>

以某种方式可以将text_field的值传递给button_to_with_filter的:option =&gt; {...}吗?我发现这个解决方案(如果它工作)非常不方便。您的意见总是很有帮助。

问候 的Matthias

3 个答案:

答案 0 :(得分:1)

在没有以任何身份审查它们的情况下输入用户提交的参数的内容似乎有点可怕。如果数据没有按预期进入,或者被制定为恶意数据,您可能会遇到各种异常。

我发现使用链式范围方法通常更容易:

def index
  bills_scope = Bill

  # Use an example Bill.with_id scope
  if (params[:with_id])
    bills_scope = bills_scope.with_id(params[:with_id])
  end

  # Repeat as required

  # Finally, use the scope to retrieve matching records
  @bills = bills_scope.paginated
end

使用像will_paginate这样的东西可以帮助你抵消和限制价值。

答案 1 :(得分:1)

如果文本字段和按钮被封装在表单中,并且按钮是提交按钮,则文本字段的值将自动被带入params散列。那你就不用处理了。我现在不记得确切的Rails助手会为你做这件事,但你想要的结果形式可能是这样的:

<% form_for :options, :url => {:action => :index}, :html => { :method => :get } do |f| %>
<%= f.text_field :filter ,:criteria, :class=>'roundRect',:id=>'name', :value=>12009%>
<%= f.submit 'Start Filter' %>
<% end %>

这可能会改变一些,因为我不知道你的方法背后的底层代码。

否则,我唯一能想到的就是在按钮上使用Javascript事件,该事件在提交之前抓取文本字段的值。

答案 2 :(得分:0)

感谢您的帮助,我遇到了named_scope并使用以下代码解决了问题:

比尔模特:

class Bill < ActiveRecord::Base
  # named_scope werden fuer Filterfunktionen bei Adminbill benoetigt
  named_scope :standard, :order => "created_at DESC"
  named_scope :limit, lambda {|*args| {:limit=>(args.first)|| 50}}
  named_scope :offset, lambda {|*args| {:offset=>(args.first || 10)}}
  named_scope :paid, :conditions=>"paid IS NOT NULL"
  named_scope :not_paid, :conditions=>{:paid=>nil}
  named_scope :test_bill, :conditions => {:test_bill=>true}
  named_scope :no_test_bill, :conditions => {:test_bill=>false}
  named_scope :find_via_bill_id, lambda {|*args|{:conditions=>{:id=>(args.first || 210)}}}
  named_scope :find_via_email, lambda {|*args| {:conditions=>{:buyer_id=>args.first}}}

控制器:

  def index
logger.debug "The object is #{current_user}"

if params[:filterInput] != nil && !params[:filterInput].empty?
  filter_array = params[:filterInput].split('&')
  bill_scope = Bill.scoped({})
  bill_scope = bill_scope.standard

  # Filtere via Regexp-Matching die Zahlen der Eingabe heraus 
  filter_array.each do |el|
    if el =~ /limit\([0-9]+\)/
      number = 
      bill_scope = bill_scope.limit(el.scan(/\d+/)[0])
    elsif el =~ /offset\([0-9]+\)/
      bill_scope = bill_scope.offset(el.scan(/\d+/)[0])
    elsif el == 'paid'
      bill_scope = bill_scope.paid
    elsif el == 'not_paid'
      bill_scope = bill_scope.not_paid
    elsif el == 'test_bill'
      bill_scope = bill_scope.test_bill
    elsif el =~ /find_via_bill_id\([0-9]+\)/
      bill_scope = bill_scope.find_via_bill_id(el.scan(/\d+/)[0])
    elsif el =~ /find_via_email\([A-Za-z0-9.@-]+\)/
      email = el.scan(/\([A-Za-z0-9.@-]+\)/)[0]
      # TODO geht bestimmt auch eleganter durch besseres Matching
      email = email.gsub("(", "")
      email = email.gsub(")", "")
      user =  User.find_by_email(email) unless User.find_by_email(email).blank?
      bill_scope = bill_scope.find_via_email(user.id)
    end
  end
  @bills = bill_scope
else 
  @bills = Bill.standard.limit.offset
end

在视图中:

<% form_tag(:action => 'index') do %>
   <%= text_field_tag 'filterInput', nil, :size => 40 %> 
  <%= submit_tag 'Start Filter'%>
<% end %>

现在您可以传入tex字段,例如以下有效表达式:付费和限制(20) 我知道控制器解决方案不是很优雅,但对我来说这是解决这个问题的最快方法。