Suppress square brackets in input names generated by simple_form - ruby-on-rails

I'm working on a bookmarkable search form - with simple_form in order to get access to some custom inputs. Since no real model object is connected, I use the :q symbol to fake one:
= simple_form_for :q, url: projects_path, method: :get do |f|
= f.input :area_id,
as: :select,
collection: (...)
= f.input :description,
as: :geocomplete
While this works, the naming conventions produce in not so nice URLs such as:
...?q[area_id]=16&q[description]=Paris&q[lng]=4.123&q[lat]=30.123
Is there a way to tell simple_form to suppress the fake :q object and produce URLs like:
...?area_id=16&description=Paris&lng=4.123&lat=30.123
Thanks for your hints!

Like #Martin wrote, it can't be done. So it's either standard form helpers or accept the square brackets. I've chosen the latter.

Related

duplicated id for fields using simple_form

I've a form in my page for each record, something like this:
- records.each do |r|
...
= simple_form_for record do |f|
= f.input :field
The problem is that each input has the same id. How can I add a prefix to generate ids like record_12_field? I've tried input_html and html options on the simple_form_for attributes but doesn't work.
The only alternative I can think of is manually setting the id for each input.
This is different to the duplication suggested, because i'm not asking how to set an id for a single field, but how to add a prefix to all of them.
The answer is using the namespace option, this answer does not appear on the duplicate. Please allow me to answer this.
Update
As Arnold mentioned, it is possible with the namespace option.
Original answer
I think it is not possible to add the prefix automatically. As a workaround you can try with:
- records.each do |record|
...
= simple_form_for record do |f|
= f.input :field, input_html: { id: "record_#{record.id}_field" }
Alternatively, you can switch to form_for and use this solution.

How to create a custom method for the hint parameter of the input method in ActiveAdmin/Simple Form gems?

From this code:
ActiveAdmin.register News do
form do |f|
f.inputs do
f.input :url
f.input :site_name
f.input :site_url
f.input :image,
as: :file,
hint: if f.object.image_url
f.template.image_tag(f.object.image_url)
else
''
end
end
f.actions
end
end
I want to extract the if clause in a method, since I have this part repeating a lot. The question is - how exactly do I do that? To clarify:
Where do I define the method - in some helper, in a new file? How do I make sure ActiveAdmin has access to this file? Do I have to create a custom ActiveAdmin controller action?
Although something like some_method(f, field) (field is in my case image) is acceptable, I would like to have it in a more generic form, so that I repeat myself less, like f.hint with the hint method inferring the field name as the first parameter of f.input. Is this possible?
Any advice on this is appreciated.
Probably the easiest way would be to simply create your own formtastic input for images that either set the hint option by default, or add in extra HTML to show an image preview. Doing so might allow you to do something like this:
f.input :image, as: :image, preview: f.object.image_url

Rails - binding versus not binding a rails collection select

So I was experiencing an error when I was attaching a collection_select to my form_for object like so:
<%= f.collection_select(:city_id, #cities, :id, :name, {:prompt => "Select a City"}, {:id => 'cities_select', multiple: true}) %>
and getting the error:
undefined local variable 'city_id'
But when I don't bind the select like so:
<%= collection_select(nil, :city_id, #cities, :id, :name, {:prompt => "Select a City"}, {:id => 'cities_select', multiple: true}) %>
It works fine.
I just want to understand the theory behind why one works and the other doesn't?
I think what's tripping you up, primarily, is the concepts you have of what's going on here.
Nothing is “binding” anything to anything by calling a method on a form helper object. There are form helper methods, like collection_select, that can be used to build HTML elements. There are form builders that have methods, like collection_select that build HTML form elements for a form tied to an object.
The issue you're having here is that the FormOptionsHelper#collection_select method and the FormBuilder#collection_select method are not the same method and do not accept the same arguments:
FormOptionsHelper#collection_select vs FormBuilder#collection_select
Pay particular attention to the arguments provided. It's also worth noticing that FormBuilder essentially delegates this work to the template (i.e. FormOptionsHelper) and adjusts the arguments as needed.

How do I generate a bunch of checkboxes from a collection?

I have two models User and Category that have a HABTM association.
I would like to generate checkboxes from a collection of Category items on my view, and have them associated with the current_user.
How do I do that?
Thanks.
P.S. I know that I can do the equivalent for a dropdown menu with options_from_collection_for_select. I also know that Rails has a checkbox_tag helper. But not quite sure how to do both of them. I know I can just do it manually with an each loop or something, but am wondering if there is something native to Rails 3 that I am missing.
Did you check out formtastic or simple_form
They have helpers to write your forms more easily, also to handle simple associations.
E.g. in simple_form you can just write
= simple_form_for #user do
= f.association :categories, :as => :check_boxes
In form_tastic you would write
= simple_form_for #user do
= f.input :categories, :as => :check_boxes
Hope this helps.
You can use a collection_select and feed it the options. Assuming you have a form builder wrapped around a user instance, you can do something like this:
form_for current_user do |f|
f.collection_select(
:category_ids, # the param key, so params[:user][:category_ids]
f.object.categories, # the collection of items in the list
:id, # option value
:name # option string
)
end
You may want to pass the :multiple => true option on the end if needed.

Generating unique HTML ids in Rails when using a repeated partial that has form_for

I have a view on my current project which does something like the following(in haml):
-#horses.each do |horse|
= render :partial => 'main/votingbox', :locals => {:horse => horse}
The in the _votingbox.html.haml file I have the following:
%div.votingbox
%span.name= horse.name
%div.genders
- if horse.male
%img{:src => 'images/male.png', :alt => 'Male'}
- if horse.female
%img{:src => 'images/female.png', :alt => 'Female'}
%div.voting_form
= form_for(Vote.new, {:url => horse_vote_path(horse)}) do |f|
= f.label :comment, "Your opinion"
= f.text_field :comment
...
a bunch of labels and input elements follow generated using the form helpers
This will generate working code but it does generate forms with the same ids for all the form elements which makes the HTML invalid once the votingbox partial is rendered a second time.
My first guess at fixing this was to specify a unique :id to form_for but that only applies to the form tag generated by form_for and not any of the tags inside the form_for block.
One definite solution to this problem is to go through and manually define my own unique ids on form_for and all the form elements I use. This is more work than I had hoped for.
Is there an easier or cleaner way to get unique ids in a similar format to the way Rails currently generates them on all my form elements?
I have removed the original answer as it is totally irrelevant to the updated version of the question.
Update: So now we know that you have an unsaved ActiveRecord object passed to the form_for call, the answer becomes simple: You can override any parameter that form_for generates. That includes the element id. And fields_for sets the context for a specific record.
= form_for(Vote.new, :url => horse_vote_path(horse), :id => dom_id(horse, 'vote')) do |f|
= f.fields_for horse, :index => horse do |fh|
= fh.text_field :whatever
…
You can override the autogenerated ids and names of all form_for content with :as like the following:
= form_for(Vote.new, :as => horse.name, {:url => horse_vote_path(horse)}) do |f|
= f.label :comment, "Your opinion"
= f.text_field :comment
So if a given horse.name is foobar, it will generate a comment field whose id is foobar_comment and name is foobar[comment]
But remember to make sure that the dynamic parameter is acceptable as an html id, a horse.name like hor$e is not acceptable as an html id and therefore might break something.
P.S: Sorry for answering very late, but at the time the question was asked, I haven't had learnt anything at all about rails! hope that might help someone out there!

Resources