如何使用具有资源丰富的URL帮助程序的ActiveModel?

时间:2014-01-08 09:32:36

标签: ruby-on-rails ruby-on-rails-3 rails-routing activemodel

一个令人困惑的问题标题需要对我希望的内容进行大量解释,这实际上并不是一个问题。

我已经在我的Rails 3.2.16应用程序中创建了一个ActiveModel(FooBarSearch)来处理ActiveRecord模型(FooBar)的搜索请求。网站上有一些地方我希望我的用户能够搜索FooBar所以我希望能够使用网址帮助程序,但我无法将其全部工作。

我怀疑问题是我必须在to_param中定义某种to_queryFooBarSearch方法。但无法找到明确的解决方案或指南。任何帮助将不胜感激。

我想写什么

- @request = FooBarSearch.new :option => 'value'
= link_to 'download csv', search_foo_bar_path(@request, :format => :csv)

目前产生什么

<a href="/foo_bar/search">download csv</a>

我想看到什么

以下是我在表单提交时在Chrome地址栏中看到的内容,因此(我假设)这就是我希望URL帮助程序生成的内容

<a href="/foo_bar/search.csv?utf8=✓&foo_bar_search%5Boption_1%5D=value&foo_bar_search%5Boption_2%5D=value_2&commit=Search">

修改

经过大量的键盘攻击后,我似乎想出了一些像上面详述的那样有效的东西。唯一的问题是我真的不知道为什么它有效?谁能解释一下?

应用程序/模型/关切/ foo_bar_search.rb

  def attributes
    { :option_1 => @option_1, :option_2 => @option_2, :option_3 => @option_3 }
  end

  def to_param
    attributes.to_param
  end

  def to_query(key = 'foo_bar_request')
    attributes.to_query(key)
  end

现有代码

/app/controllers/foo_bars_controller.rb

class FooBarController < ApplicationController
  def
    if params[:foo_bar_search]
      @request = FooBarSearch.new params[:for_bar_search]
    else
      @request = FooBarSearch.new
    end

    respond_to do |format|
      format.html
      format.csv { @request.to_csv }
    end
  end
end

/app/views/foo_bars/search.html.haml

%h1= @page_title = "Foo Bar Search"

= form_for(@request, :url => search_foo_bar_path, :method => :get) do |f|
  .form_section
    %table
      %tr
        %th Search Option 1
        %td= f.select :some_option_id
    = submit_tag 'Search!'

配置/ routes.rb中

  resources :foo_bar do
    collection do
      get :search
      post :search
    end
  end

应用程序/模型/关切/ foo_bar_search.rb

class FooBarSearch
  extend ActiveModel::Naming
  include ActiveModel::Conversion

  # Required by ActiveModel::Conversion
  def persisted?
    false
  end

  def initialize(options = {})
    # ...
  end

  # I think i may need #to_param and/or #to_query here, 
  # but so far have not been able to get this working...
end

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

我有类似的问题,可能会有所启发。

ActiveModel::Conversion#to_param上查看来源。查看它是如何为您定义to_param的,并返回对象的键,但仅当persisted?返回true时才会返回。

即使to_param被硬编码到:id,您的persisted?定义也会包含false(以及所有其他不相关的属性)。这解释了为什么它适合你,但你的覆盖不是真的正确。

为了解决我的类似问题,我将持久化定义为:

# assume object is persisted if it has an id
def persisted?
  self.id.present?
end

另外,您可以查看Barebone models to use with ActionPack in Rails 4.0上的Platformatec博客。如果你include ActiveModel::Model,它会包含你正在使用的其他ActiveModel模块,initializepersisted?方法以及其他好东西,所以你需要做的就是覆盖{正如我所描述的那样{1}}。

谢谢你的提问!它帮我把问题与我自己的问题联系起来。