Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Ruby/Rails方法帮助_Ruby On Rails_Ruby_Ruby On Rails 3_Methods_Arguments - Fatal编程技术网

Ruby on rails Ruby/Rails方法帮助

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

所以,我在创建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.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相关的方法中发生的情况的描述:

  • 如果传递给此方法的第三个参数不是散列,则它将该arg设置为名称并将其删除(
    args.shift
    ),否则使用生成器名称

  • 然后查看下一个arg(即第四个arg)。如果它是一个散列,那么它会将选项设置为该参数并删除该参数,否则它会将其设置为空散列

  • 然后查看下一个arg(第5个arg)。如果它是散列,那么它将其设置为html_选项并删除该参数,否则html将设置为{}

  • 使用args*可以使调用方法变得更简洁(尽管方法中的实现可能不是这样)。如果您没有要传递的“名称”,请不要这样做:

    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