Rails 3.1, passing parameters for colection_select from controller - ruby-on-rails-3

I have this collection_select usage in my view:
<%= collection_select(:production_year, :id, #car_models, :id, :name, { :prompt => "Year" }, { :disabled => "disabled" } ) %>
But it seems, that i'll add much logic for this select box. So i want pass parameters for this collection_select from my controller. How can i do this?
Was trying to pass array with parameters, but got many errors. Pls show correct way for this.

In your controller: #collection_select_params = [ ... ]
And in your view: <%= collection_select(*#collection_select_params) %>
The * prefix will indicate to ruby that this array is to be passed as an args list.

Related

Select menus in Rails 3?

I have the following code in my Rails 3 application, it's supposed to be displaying a select box with each asset_type record:
assets_helper
def asset_type_all_select_options
asset_type.all.map{ |asset_type| [asset_type.name, asset_type.id] }
end
_form.html.erb (Asset)
<%= f.select :asset_type_id, asset_type_all_select_options, :class => "input-text", :prompt => '--Select-----' %>
and here are my models:
asset.rb
belongs_to :asset_type
asset_type.rb
has_many :assets
Using the above code I get the following error:
undefined local variable or method `asset_type' for #<#<Class:0x007f87a9f7bdf8>:0x007f87a9f77d48>
Am I doing something wrong? Will this method not work with double barrel model names? Any pointers would be appreciated!
The variable asset_type in your assets_helper file is not defined. You would need to pass it in to the helper method
def asset_type_all_select_options(asset_type)
# ...
end
Or use an instance variable that you define in the controller (e.g. #asset_type).
However, you can simplify this by using the #collection_select form helper.
_form.html.erb (Asset)
<%= f.collection_select :asset_type_id, AssetType.all, :id, :name, { prompt: '--Select-----' }, class: 'input-text' %>
Take a look at the API for #collection_select for details.

simple_form - how do I create radio buttons with nested input text boxes

I'm using simple_form to render my forms and trying to get the following behavior: I want the client to choose from 3 options. In every option he supplies additional field or two.
So I'd like something like this:
Please set your preferences:
o Pay me on a specific day - [input field to get the day]
o Pay me a specific amount of money - [input field for the amount]
o Pay me on a regular basis - [radio buttons to choose between weekly/monthly basis]
I can create the radio buttons as follows, but can't add nested fields under them:
<%= simple_form_for #client, action: 'edit_payment_method' do |f| %>
<%= f.input :payment_type, label: 'Please set your preferences:',
collection: [ ['Pay me on a specific day', :specific_day],
['Pay me a specific amount of money', :specific_money],
['Pay me on a regular basis', :regular_basis]
], as: :radio_buttons %>
<%= f.button :submit, 'Submit' %>
<% end %>
What would be the best way to create the nested text boxes?
As for the fields, I don't need to send them to different controllers (per payment_type), it's fine if I send them all to one method and read the relevant values according to the payment type he chose.
Thanks! Zach
The simple_form collection_radio_buttons is likely what you want. Its options parameter accepts a block which allows you to customize what is rendered with each radio button. Take a look at the example in rdocs here.
Edited:
Here is basically what you need to do in a relatively generic way (hasn't been tested, but I'm running something similar). Put your additional controls in the partial for each radio button:
<% radio_buttons = [
{ :text => 'Pay me on a specific day', :value => :specific_day, :partial => "<textbox_partial_name>", :locals => { :any_locals => :your_partial_needs} },
{ :text => 'Pay me a specific amount of money', :value => :specific_money, :partial => "<textbox_partial_name>", :locals => { :any_locals => :your_partial_needs} },
{ :text => 'Pay me on a regular basis', :value => :regular_basis, :partial => "<radio_partial_name>", :locals => { :any_locals => :your_partial_needs} },
] %>
<%= simple_form_for #client, action: 'edit_payment_method' do |f| %>
<%= f.label t("account.update_payment_method.title") %>
<%= f.collection_radio_buttons :payment_type, (collection.collect do |r| [r[:text], r[:value], r[:partial].nil? ? "" : r[:partial], r[:locals].nil? ? {} : r[:locals]] end), :second, :first do |builder| %>
<%= builder.label{builder.radio_button(:class => 'payment_method_options') + builder.text} %>
<% unless builder.object[2].blank? %>
<%= render :partial => builder.object[2], :locals => builder.object[3] %>
<% end %>
<% end %>
<%= f.button :submit, 'Submit' %>
<% end %>
You can omit :partial for any radio button that doesn't need additional controls, along with :locals if your partial doesn't need it. There are also ways to simplify this code for your situation, but this example illustrates how to add more complex control structures to each radio button if needed.
OK.. I've managed to solve this somehow, not sure that it's the best alternative, but I'm posting it so if someone needs it in the future he at least has something to start with.
I went with creating a "regular" form using simpleform and then using JQuery to move the inner input fields (which were created regularly) next to the radio buttons.
Add JQuery support to your rails app:
add gem "jquery-rails" to your Gemfile
bundle install
rails generate jquery:install
The form I've used (regular simpleform):
Notice the class that is attached to the radio buttons and the ids that are attached to the input fields. I'll use it later to move the elements.
<%= simple_form_for #client, url: 'update_payment_data' do |f| %>
<%= f.input :payment_type, label: t('account.update_payment_method.title'),
input_html: { class: 'payment_method_options' },
collection: [ [t('account.update_payment_method.sum_based.title'), :amount],
[t('account.update_payment_method.days_in_month_based.title'), :days_in_month],
[t('account.update_payment_method.optout.title'), :optput]
], as: :radio_buttons %>
<%= f.input :payment_amount, label: "Payment amount threshold",
input_html: { id: 'payment_amount_box' } %>
<%= f.input :payment_days_in_month, label: "Payment days in month",
input_html: { id: 'payment_days_in_month_box' } %>
<%= f.button :submit, t('account.update_payment_method.update') %>
<% end %>
In the same page - the JQuery code:
<script>
$(document).ready(function() {
var amount_box = $("#payment_amount_box");
var amount_box_parent = amount_box.parent();
amount_box.detach().appendTo($(".payment_method_options:eq(0)").parent());
amount_box_parent.remove();
var dim_box = $("#payment_days_in_month_box");
var dim_box_parent = dim_box.parent();
dim_box.detach().appendTo($(".payment_method_options:eq(2)").parent());
dim_box_parent.remove();
});
</script>
I think it's pretty self-explanatory, it just looks for what is going to be the inner input fields (by id) and moves them into the appropriate place under the span that simpleform creates for each radio button.
I had to play a little bit with the css to make it look how I wanted (display:block for example), but that's more or less it.
Hope it helps.. Zach

Rails virtual attribute array

I am creating a virtual attribute in my model:
def entities
#entities = Array.new()
#entities.push(self.contact.name)
#entities.push(self.contact.partner.name) if self.contact.partner
#entities.push('Joint') if self.contact.partner
#entities
end
Then in my form I'm trying to use this array from a nested array. I'm using simple form so it looks like this
<%= f.input :ownership, collection: :entities, :include_blank => false, :label => false %>
However this gives me an error:
undefined method `to_a' for :entities:Symbol
If I have created an array, I don't understand why it isn't rendering as an array. What am I missing?
You can't use :entities as the collection:
<%= f.input :ownership, collection: :entities ...%>
That doesn't work. The error indicates that Simple Form is attempting to convert the argument :entities to an array, which is causing an error.
You need to give it an actual collection:
<%= f.input :ownership, collection: #object.entities ... %>

Rails simple_form pre-populated input values lost during server side form validation [duplicate]

This question already has an answer here:
Rails simple_form server side validations lost URL params
(1 answer)
Closed 8 years ago.
I have a simple_form in my rails app that I want to pre-populate
some of the fields with URL parameters.
Example URL is:
http://localhost:3000/surveys/new?phone=8675309
This pre-populate the phone field corretly using this code:
<%= simple_form_for #survey, :html => { :class => 'form-horizontal' } do |f| %>
<%= f.input :state, :required => true %>
<%= f.input :zip, :required => true %>
<%= f.input :phone, :required => true, :input_html => { :value => params['phone'] } %>
<% end %>
The problem is if the form is submitted without a required field
the form is reloaded but the phone input value is not retained.
If the form is submitted without a value for zip
the reloaded page with validation errors in red URL is now:
http://localhost:3000/surveys
If, say, the state field is correct but no zip code the form is reloaded
with an error msg saying zip is required.
The state value is retained however the phone is not.
I guess it has to do with :value => params['phone'] in the f.input for the phone.
Is there anyway I can populate the simple_form with URL paramenters
on it's initial load and have those value retained if the serverside validation fails?
Many thanks.
Remove the :value from your view:
<%= f.input :phone, :required => true %>
and use this URL:
http://localhost:3000/surveys/new?survey[phone]=8675309
That should generate the "standard" survey parameter hash expected by the controller. In my test, that works the same as if the user had typed in the value, with the usual validation handling.
Inside the controller, the hash is called params[survey] with individual parameters represented as params[survey][phone], params[survey][zip], etc.
With the help of this answer, I found that you can generate the URL with the link_to signature link_to(body, url_options = {}, html_options = {}):
<%= link_to 'New survey', { :controller => "surveys",
:action => "new",
:survey => { :phone => "8675309", :zip => "10001" } },
{ :target => "_blank" } %>
Note that url_options is the first hash, and within that hash you have a survey hash for pre-loading values. Finally comes the optional hash of html_options (where I added target="_blank" for illustration purposes).
Thanks Mark,
I re-posted this question again a while back and it was answered corretly here:
Rails simple_form server side validations lost URL params

assigning parameters to a model in a link_to helper

if am trying to pass a parameter through a link and assign it to a specific model. here is the code i'm working with:
<%= link_to ( image_tag("item.png", :size => "50*50", :border=> 0, :alt => "item", :title => "item"), {:action => 'initialize_order', :frame_id => 1 }) %>
right now :frame_id is getting passed through as:
{"frame_id"=>"1"}
i want the parameter to be assigned to the model :order, returning:
"order"=>{"frame_id"=>"1"}
i know the answer must be simple but i've searched for a while now.
try this in your url args:
{:action => 'initialize_order', :order => {:frame_id => 1 }}
alternatively, since you only have one parameter, just pass it as :id and assign it in the controller.
Even better, build your app using RESTful routes, with an orders_controller and an initialize method. If orders and frames have a parent-child relationship, then nest them in your resources. That way you can use all the path generators.