1

I'm not sure if this is possible, feel free to smack me back to reality if it's not.

I have a controller, Reports, that displays a table in the view of a method/action called 'filtered', and I'd like to add a "filtering" property to it. My approach to this was adding an extra route, to keep the URLs tidy.

 reports      GET /reports(.format)                  reports#filtered
 args_reports GET /reports/:concept/:id(.format)     reports#filtered

So, without arguments, I'd get the full table, and if I add the two extra parameters (concept and id), I'd get a filtered table based on the criteria selected. This works well when I do it manually.

Now, I'd like to pick both the :concept and :id from a dropdown menu box. The :concept data is nothing but a selection of two fields (which are hardcoded into the selection to avoid any possible code injection), while the :id data is picked by the user from the dropdown menu. I'm not too sure how to implement this.

I'm using HAML, and I currently have the following:

On the controller:

 @types=Type.all
 @type_current[:selected]=@types.last.id

On the view:

 #rightdiv
   = form_tag(arg_reports_path(:concept => 'type')) do
     %table
       %tr
         %td Type
         %td=collection_select(:type, :id, @types.all, :id, :name, {:selected => @type_current[:selected]})
         %td=submit_tag 'Filter' 

But this tells me that I'm missing a required key, which is :id. I understand that perfectly, but where do I provide that data? I want the user to be able to pick that id, so I do not know before-hand what to include here, or how to tell the form_tag to pick up the id from the collection_select. Is that possible? Or I'm totally wrong in my interpretation?

Also, an small side question. The collection_select tag will provide a hash of "type[id]", is there a way to make it do "type" only instead of a hash?

Thanks in advance.

EDIT:

An example of what I'm trying to achieve is to get the form to send me to:

 /reports/type/9

Or, if we use the other concept:

 /reports/location/7

9 and 7 are the IDs of type and location, respectively. 'type' and 'location' are fields of the model Report, of which there're several and are contained in their respective models.

The dropdown menus would be populated with the names and ids of the tables 'type' and 'location', which are placed one after the other in the view. The user would select one of the two, which would then send them to a filtered table with the criteria picked.

Community
  • 1
  • 1
dev404
  • 1,088
  • 13
  • 34

1 Answers1

2

If I understand correctly, /reports and /reports/:concept/:id both go to the same action, right? If this is the case, what you can do is just use /reports as the action for the form, and pass concept as a hidden input. The dropdown will have a name of id. So when the user submits the form, you still get a params[:concept] and a params[:id] in the controller. The downside of this is that the url will only appear as /reports.

What you want to achieve isn't possible without a little javascript. Anything that you need to change in the html that requires user input need javascript. Look at Changing the action of a form with javascript/jquery.

The collection_select tag accepts it's last parameter (7th or 6th) a list of html options. Change your code to the following so you get a

collection_select :type, :id, @types.all, :id, :name, { :selected => @type_current[:selected] }, { :name => 'type' }
Community
  • 1
  • 1
jvnill
  • 29,479
  • 4
  • 83
  • 86
  • Oh, that's clever. That works to pass the name instead of the hash. Now, the other thing, the concept is already being sent in arg_reports_path(:concept => 'type') in the form_tag, what I'm not getting yet is the id. I don't mind having an ugly URL afterwards, I just need the ID to be "delegated" to the collection_select. Is that what you mention that would require some javascript? – dev404 Feb 13 '14 at 04:37
  • I guess what I'm really asking is if it is possible to pass an id with a form_tag in a route that does require an :id. A dynamic id, mind you. – dev404 Feb 13 '14 at 05:16
  • no you can't. using named routes require you to have the values of the needed parameters, in this case, those are `:concept` and `:id`. which is the reason why I suggested to just use `reports_path` since you'll get an error when you use `arg_reports_path(:concept => 'type')` – jvnill Feb 13 '14 at 16:44
  • Thank you! Sometimes I get carried over with an idea with the presumption that it is possible. – dev404 Feb 13 '14 at 20:20