Ruby on rails Ruby/Rails方法帮助
所以,我在创建ruby方法方面是个新手。我从gem(meta_搜索)中获得了以下方法,但我需要更改默认行为。方法如下:Ruby on rails Ruby/Rails方法帮助,ruby-on-rails,ruby,ruby-on-rails-3,methods,arguments,Ruby On Rails,Ruby,Ruby On Rails 3,Methods,Arguments,所以,我在创建ruby方法方面是个新手。我从gem(meta_搜索)中获得了以下方法,但我需要更改默认行为。方法如下: def sort_link(builder, attribute, *args) raise ArgumentError, "Need a MetaSearch::Builder search object as first param!" unless builder.is_a?(MetaSearch::Builder) attr_name = attribute.t
def sort_link(builder, attribute, *args)
raise ArgumentError, "Need a MetaSearch::Builder search object as first param!" unless builder.is_a?(MetaSearch::Builder)
attr_name = attribute.to_s
name = (args.size > 0 && !args.first.is_a?(Hash)) ? args.shift.to_s : builder.base.human_attribute_name(attr_name)
prev_attr, prev_order = builder.search_attributes['meta_sort'].to_s.split('.')
current_order = prev_attr == attr_name ? prev_order : nil
new_order = current_order == 'asc' ? 'desc' : 'asc'
options = args.first.is_a?(Hash) ? args.shift : {}
html_options = args.first.is_a?(Hash) ? args.shift : {}
css = ['sort_link', current_order].compact.join(' ')
html_options[:class] = [css, html_options[:class]].compact.join(' ')
options.merge!(
builder.search_key => builder.search_attributes.merge(
'meta_sort' => [attr_name, new_order].join('.')
)
)
link_to [ERB::Util.h(name), order_indicator_for(current_order)].compact.join(' ').html_safe,
url_for(options),
html_options
end
此方法返回搜索的排序链接。输出如下所示:
<a class="sort_link asc" href="/photos?search[meta_sort]=average_rating.desc">Best Photography ▲</a>
对此
new_order = current_order == 'desc' ? 'asc' : 'desc'
…但情况正好相反。我真正需要的是能够指定一个选项,并在该选项通过时反转该行为
所以我的问题是:我真的不明白*arg是如何传递的。据我所知,这些行采用了rails link\u to方法的选项和html\u选项哈希
options = args.first.is_a?(Hash) ? args.shift : {}
html_options = args.first.is_a?(Hash) ? args.shift : {}
我想做的是在选项散列中添加一个自定义选项,如果定义了该选项,则反转排序公式。我试着这么做
if defined? options[:sort_preference] && options[:sort_preference]==:desc
new_order = current_order == 'desc' ? 'asc' : 'desc'
options.delete(:sort_preference)
else
new_order = current_order == 'asc' ? 'desc' : 'asc'
options.delete(:sort_preference)
end
。。。但这不起作用,它只是保留了标准行为,并将:sort_首选项传递到URL中,如下所示:
<a class="sort_link asc" href="/photos?search[meta_sort]=average_rating.desc&sort_preference=desc">Best Photography ▲</a>
在上面的链接中,sort\u preference
不应该出现在URL中,search[meta\u sort]
应该是average\u rating.asc
——因为链接显示的是呈现的相反内容
所以,很明显,我的尝试没有成功,因为我真的不明白这个方法中发生了什么。我希望回答这个问题的答案是:
- 有助于理解*args的工作原理
- 解释我尝试向此方法添加选项失败的原因
- 如何修复它的示例
非常感谢您的关注
*args
只意味着可以传递无限数量的参数。所以这个方法首先需要两个参数(builder和attribute),然后可以传递任意数量的参数。以下是与args相关的方法中发生的情况的描述:
args.shift
),否则使用生成器名称sort_link(some_builder,some_attribute,nil,options)
您可以这样做:
sort_link(some_builder,some_attribute,options)
如果您没有参数,它不会强制您为name添加参数
因此,要使代码正常工作,此方法需要将options作为第4个参数,options散列需要包含:sort_preferences
。调用排序链接的代码是什么样子的?您需要将此选项插入该散列中,然后才能使用此方法
此方法假定您希望在第一次单击时按升序排序,在第二次单击时按降序排序。我想要相反的行为
meta_搜索gem支持这一点。没有必要修改gem的代码。在控制器中,查询数据后,将@search对象上的meta_sort属性设置为所需的字段和排序顺序。加载视图时,数据将按预期进行排序
例如,在Posts控制器中,您可以执行以下操作以将默认排序设置为标题字段(降序):
def index
@search = Post.search(params[:search])
@search.meta_sort ||= 'title.desc'
@posts= @search.all
end
要回答您的问题,调用代码是:=sort\u link@search,:average\u rating,“Best Photography”,:sort\u preference=>:desc
好的,我现在知道了--我需要移动options=args.first.a?(散列)?args.shift:{}
向上移动以使if语句工作。一旦那条线向上移动,它就会工作。谢谢你的解释,这很有帮助!嘿,谢谢你——我仍然认为默认行为应该是内联的,而不是控制器中的,但是这是一个很好的解决方案。
def index
@search = Post.search(params[:search])
@search.meta_sort ||= 'title.desc'
@posts= @search.all
end