0

I have 3 lists of links on a page of my site which should change there parameters. The links are:

      ul
        li = link_to "View all", coasters_path

      ul
        li
          - if params[:type] == "steel"
            - params.delete :type
            = link_to "Steel", coasters_path(params)
          - else
            = link_to "Steel", coasters_path(params.merge({type: "steel"}))

        li
          - if params[:type] == "wood"
            - params.delete :type
            = link_to "Wooden", coasters_path(params)
          - else
            = link_to "Wooden", coasters_path(params.merge({type: "wood"}))

        li
          - if params[:type] == "powered"
            -params.delete :type
            = link_to "Powered", coasters_path(params)
          - else
            = link_to "Powered", coasters_path(params.merge({type: "powered"}))

      ul
        li
          - if params[:letters] == "#"
            - params.delete :letters
            = link_to "#", coasters_path(params)
          - else
            = link_to "#", coasters_path(params.merge({letters: "#"}))

        li
          - if params[:letters] == "a-e"
            - params.delete :letters
            = link_to "A-E", coasters_path(params)
          - else
            = link_to "A-E", coasters_path(params.merge({letters: "a-e"}))

        li
          - if params[:letters] == "f-j"
            - params.delete :letters
            = link_to "F-J", coasters_path(params)
          - else
            = link_to "F-J", coasters_path(params.merge({letters: "f-j"}))

        li
          - if params[:letters] == "k-o"
            - params.delete :letters
            = link_to "K-O", coasters_path(params)
          - else
            = link_to "K-O", coasters_path(params.merge({letters: "k-o"}))

        li
          - if params[:letters] == "p-t"
            - params.delete :letters
            = link_to "P-T", coasters_path(params)
          - else
            = link_to "P-T", coasters_path(params.merge({letters: "p-t"}))

        li
          - if params[:letters] == "u-z"
            - params.delete :letters
            = link_to "U-Z", coasters_path(params)
          - else
            = link_to "U-Z", coasters_path(params.merge({letters: "u-z"}))

The problem, is if I go to the page afresh at just coasters_path or /coasters and click the Steel link, that is fine so the params are ?type=steel. However, I then click on A-E and the params deletes the type=steel and replaces it with letters=a-e.

If I do this the opposite way around and do A-E first followed by Steel, it adds ?letters=a-e and then adjoins &type=steel onto the end thereby chaining the filters.

Any idea why this is happening and how it can be solved? I just cannot see any problems with the code?

1 Answer 1

1

The problem is that you are mutating the params hash as you go along: when you are on the steel page then you delete :type from params pretty much straightaway, so it's not in the hash by the time you are rendering your letters links.

I don't entirely understand what you are trying to do but I would consider mutating the params hash like this really bad form. It's also messy have all that manipulation in the view.

If you need to manipulate the params then write a helper method that returns an updated copy, eg you might write something like

def params_skipping_type type_to_skip
  if params[:type] == type_to_skip
    params.except(:type)
  else
    params.merge(:type => type_to_skip)
  end
end

Then you can get rid of those if statements in your view and just write

            = link_to "Steel", coasters_path(params_skipping_type("steel"))
Sign up to request clarification or add additional context in comments.

5 Comments

Ok, I'll look at that. Instead of mutating the params hash, how could I accomplish this then? Basically the links are in two sections. type and letters, if you click steel the coasters show only the steel ones. If you then click steel again, it should remove the steel from the params and show them all again. If you had clicked wooden, the type filter would have changed to now show all wooden. The letters work the same way. So filteres need to be on or off. and only one filter per the type section and the letters section.
The code I posted is how you could do that - write helper methods that will return updated copies of the params hash
It half works. The problem is that if type is set to say, wood and you look at where the links will go to, the Steel links goes to type=wood, the wood link goes to no type at all and the powered link goes to type=wood. If the same type is clicked as is currently selected then type should be removed from params, if a different type is clicked then the type should switch to the new one.
Ah, I had misunderstood. I've changed the logic, although the method name isn't quite right now.
Perfect! I had to make a couple of changes to add classes to li's and so on. But brilliant! This was going round and around my head and driving me mental. Thanks for helping.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.