一个令人困惑的问题标题需要对我希望的内容进行大量解释,这实际上并不是一个问题。
我已经在我的Rails 3.2.16应用程序中创建了一个ActiveModel(FooBarSearch
)来处理ActiveRecord模型(FooBar
)的搜索请求。网站上有一些地方我希望我的用户能够搜索FooBar
所以我希望能够使用网址帮助程序,但我无法将其全部工作。
我怀疑问题是我必须在to_param
中定义某种to_query
或FooBarSearch
方法。但无法找到明确的解决方案或指南。任何帮助将不胜感激。
- @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">
经过大量的键盘攻击后,我似乎想出了一些像上面详述的那样有效的东西。唯一的问题是我真的不知道为什么它有效?谁能解释一下?
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
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
%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!'
resources :foo_bar do
collection do
get :search
post :search
end
end
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
感谢您的帮助
答案 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模块,initialize
和persisted?
方法以及其他好东西,所以你需要做的就是覆盖{正如我所描述的那样{1}}。
谢谢你的提问!它帮我把问题与我自己的问题联系起来。