Note that there are some explanatory texts on larger screens.

plurals
  1. PORuby/Rails Method Help
    primarykey
    data
    text
    <p>So, I'm pretty much a newbie at creating ruby methods. I've got the following method from a gem (meta_search), but I need to change the default behavior. Here's the method:</p> <pre><code>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 &gt; 0 &amp;&amp; !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 =&gt; builder.search_attributes.merge( 'meta_sort' =&gt; [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 </code></pre> <p>This method returns a sort link for a search. The output looks like this:</p> <pre><code>&lt;a class="sort_link asc" href="/photos?search[meta_sort]=average_rating.desc"&gt;Best Photography ▲&lt;/a&gt; </code></pre> <p>Here's the problem: this method assumes that you want to sort in ascending order on the first click, and descending order on the second. I want the opposite behavior. I see that I could change this...</p> <pre><code>new_order = current_order == 'asc' ? 'desc' : 'asc' </code></pre> <p>to this...</p> <pre><code>new_order = current_order == 'desc' ? 'asc' : 'desc' </code></pre> <p>...but that just reverses the situation. What I really need is to be able to specify an option and reverse the behavior if that option is passed.</p> <p>So here's my problem: I don't really understand how the *args are passed. From what I can tell these lines are taking the option and html_option hashes for rails link_to method...</p> <pre><code>options = args.first.is_a?(Hash) ? args.shift : {} html_options = args.first.is_a?(Hash) ? args.shift : {} </code></pre> <p>What I'd like to do is add a custom option to the options hash, and if that option is defined reverse the sort equation. I tried to do this...</p> <pre><code>if defined? options[:sort_preference] &amp;&amp; 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 </code></pre> <p>... but that didn't work, it just kept the standard behavior and passed :sort_preference into the URL like so:</p> <pre><code>&lt;a class="sort_link asc" href="/photos?search[meta_sort]=average_rating.desc&amp;sort_preference=desc"&gt;Best Photography ▲&lt;/a&gt; </code></pre> <p>In the link above, <code>sort_preference</code> shouldn't appear in the URL, and <code>search[meta_sort]</code> should be <code>average_rating.asc</code> -- since the link shows the opposite of what rendered.</p> <p>So, obviously, my attempt didn't work because I don't really understand what's going on in this method. What I'm hoping for in answer to this question is:</p> <ul> <li>A little help understanding how *args works</li> <li>An explanation of why my attempt to add an option to this method failed</li> <li>An example of how to fix it</li> </ul> <p>Thank you very much for taking a look!</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload