Ruby on Rails - Adding variable to params[] - ruby-on-rails

In the controller, how can I add a variable at the end of a params[]?
If I try this I get an error: params[:group_] + variable
How should it be done?
Edit per request
Ok, I have a form that sets groups of radio buttons with names like this:
group_01DRN0
Obviously I have different groups in the form (group_01AAI0, group_01AUI0, etc.) and the value is set according to the radio button selected within the group:
Radio button "group_01DRN0" could have value of "21" or "22" or "23", radio button "group_01AAI0" could have value of "21" or "22" or "23", etc.
In the DB I have every code (01DRN0, 01AAI0, 01AUI0, etc) so I want to select them from DB and iterate in the params value so I can get the radio button group value, I've tried this with no luck:
#codes=Code.get_codes
for c in #codes
#all=params[:group_] + c.name
end
Thanks.

p = params
p[:new_param_name] = new_param_value
It works for me (rails 3.2).
Nota: using p instead of altering params avoids altering original parameters.

params looks like a hash, but it really isn't. So if you need to "augment" params as you deal with the incoming data in your controller, invent a new data structure that includes either params or its members.
Added:
Maybe you're looking for
#codes=Code.get_codes
#all = []
for c in #codes
#all << params["group_#{c.name}"]
end

Related

rails controller invoking params of nested attributes

Submitting the following parameters
Parameters: {[...] "physicalinventario"=>{[...] "physicalinventarioitems_attributes"=>{"0"=>{"quantity"=>",85"}}}, "commit"
The goal is to intercept the quantity parameter at the physicalinventarioitem controller create action, and sanitize it for possible comma as decimal value being input
if params[:physicalinventario][:physicalinventarioitems_attributes][:quantity].include? ","
params[:physicalinventarioitem][:quantity] = params[:physicalinventario][:physicalinventarioitems_attributes][:quantity].tr!(',', '.').to_d
end
However, the syntax is wrong as no value after the comma is being handled.
#Alex answer is fine if you have only one quantity.
but what if you have multiple quantites,
eg: {"0"=>{"quantity"=>",85"},"1"=>{"quantity"=>",90"}}
So, here is the answer which also achieves that requirement for multiple nested attributes.
hash = {"physicalinventario"=>{"physicalinventarioitems_attributes"=>{"0"=>{"quantity"=>",85"},"1"=>{"quantity"=>",90"}}}}
The code that you require,
hash["physicalinventario"]["physicalinventarioitems_attributes"].each do |key, value|
if value["quantity"].include? ","
value["quantity"] = value["quantity"].tr!(',', '.').to_f
end
end
Here is the resultant hash,
`{"physicalinventario"=>{"physicalinventarioitems_attributes"=>{"0"=>{"quantity"=>0.85}, "1"=>{"quantity"=>0.9}}}}`
Looks like you've missed ["0"] in the chain to get :quantity.
Should be
params[:physicalinventario][:physicalinventarioitems_attribu‌tes]["0"][:quantity]
Most convenient Rails way to sanitize(normalize) data in a model.
To don't create duplicates, more here How best to sanitize fields in ruby on rails

rails "where" statement: How do i ignore blank params

I am pretty new to Rails and I have a feeling I'm approaching this from the wrong angle but here it goes... I have a list page that displays vehicles and i am trying to add filter functionality where the user can filter the results by vehicle_size, manufacturer and/or payment_options.
Using three select form fields the user can set the values of :vehicle_size, :manufacturer and/or :payment_options parameters and submit these values to the controller where i'm using a
#vehicles = Vehicle.order("vehicles.id ASC").where(:visible => true, :vehicle_size => params[:vehicle_size] )
kind of query. this works fine for individual params (the above returns results for the correct vehicle size) but I want to be able to pass in all 3 params without getting no results if one of the parameters is left blank..
Is there a way of doing this without going through the process of writing if statements that define different where statements depending on what params are set? This could become very tedious if I add more filter options.. perhaps some sort of inline if has_key solution to the effect of:
#vehicles = Vehicle.order("vehicles.id ASC").where(:visible => true, if(params.has_key?(:vehicle_size):vehicle_size => params[:vehicle_size], end if(params.has_key?(:manufacturer):manufacturer => params[:manufacturer] end )
You can do:
#vehicles = Vehicle.order('vehicles.id ASC')
if params[:vehicle_size].present?
#vehicles = #vehicles.where(vehicle_size: params[:vehicle_size])
end
Or, you can create scope in your model:
scope :vehicle_size, ->(vehicle_size) { where(vehicle_size: vehicle_size) if vehicle_size.present? }
Or, according to this answer, you can create class method:
def self.vehicle_size(vehicle_size)
if vehicle_size.present?
where(vehicle_size: vehicle_size)
else
scoped # `all` if you use Rails 4
end
end
You call both scope and class method in your controller with, for example:
#vehicles = Vehicle.order('vehicles.id ASC').vehicle_size(params[:vehicle_size])
You can do same thing with remaining parameters respectively.
The has_scope gem applies scope methods to your search queries, and by default it ignores when parameters are empty, it might be worth checking

save multiple parameters in a loop, rails controller

I've created a form with about 40 fields available to edit, I'm trying to save them to a database using the controller. I currently have this code:
c = Form.find(params[:id])
if c
params.each do |k,v|
c.k = params[:v]
end
Which doesn't work, I get this error: undefined method 'k='
if I was going to write them all out manually it would look like this:
c = Form.find(params[:id])
if c
c.title = params[:title]
c.reference = params[:reference]
....
etc.
Assuming that you're trying to update the attributes on your Form record based on what gets passed into params, try this as a basic outline:
c = Form.find_by_id(params[:id])
if c
params.each do |k, v|
c[k] = v
end
c.save!
end
Your original code's use of params[:v] was probably not doing what you were intending, and you really meant for it to be params[:k] instead. However there's actually no need to look up the value for that key inside the loop like that because you already have the value at hand in v.
Here's a quick rundown on the ways of interacting with ActiveRecord attributes: http://www.davidverhasselt.com/2011/06/28/5-ways-to-set-attributes-in-activerecord/
i dont know what you are trying todo but your code seems to be very odd. Solution is as follow
c.send "#{k}=", params[:v]
What about
c = Form.find(params[:id])
c.update_attributes(params[:form])
Note that I guessed the [:form] part in the second line, it depends on your form. check your html source, and see if your fields are something like this:
<input name="form[field_name]" ...
As you see, name contains an "array like" form. Check your HTML source and adapt (so if its name="foo[field_name]", you need to use c.update_attributes(params[:foo]))

Display collection value using their attributes name

I want to display value of collection by passing their respective attribute name.
#mandates is the result of an active-record query.
#tabattributes contains array of attribute names previously selected by users.
The code below show field attributes but I want the value of these field instead.
I've tried several syntaxes but errors occurs each time.
How can I modify my code to do that?
#mandates.map do |f|
#tabattributes.each { |att| " #{att} "}
end
If #mandates is a result set that contains models with attributes a, b, and c and #tabattributes is the array %w{a b} (i.e. you want to extract a and b from each element of #mandates) then:
a = #mandates.map { |m| m.attributes.slice(*#tabattributes) }
will give you an array of hashes with keys 'a' and 'b'. For example:
#tabattributes = %w{id created_at}
slices = #mandates.map { |m| m.attributes.slice(*#tabattributes) }
# slices is now like [ { 'id' => ..., 'created_at' => ... }, ... ]
If you only want the values and don't care about the keys then perhaps this will work for you:
#mandates.map { |m| m.attributes.slice(*#tabattributes).values }
That would give you an array-of-arrays. The first array-of-hashes would probably be easier to work with though.
If you can get at #mandates before accessing the database then you could slice out just the columns you're interested inside the database with something like this:
#mandates = Mandate.select(#tabattributes)
slices = #mandates.map(&:attributes)
If I understand you right, you have an array of elements, and you want to have an array containing the name of each element, is that it ? If yes, then array.map {|elem| elem.name} should do it. There is a shorter form (array.map(&:name)) which does the same, if you're interested in how this is working, I can detail.

Rails 3, best way to be DRY with radio button labels?

Suppose for an integer field named 'favfood' we represent the radio button choices as
0 indicates "no favorite"
1 indicates "Wine and cheese"
2 indicates "Burger with everything"
On our _edit view we display the radio buttons with the friendly labels above
On the /show view and /index view (and in several other places) when we display the user preference we display the same corresponding long text.
It seems non-DRY to put literal strings next to each radio button in _edit and then provide some logic to display the SAME literal string on /show and /index etc etc etc based upon the current value.
Furthermore, we have to repeatedly use the SAME logic that says if the value=1 display "The first choice", if the value = 2 display "The second choice".
What's the "rails-way" to handle user-friendly labels for radio labels so the labels (AND their association with values of the field) are defined once ?
There are two things you should do. One use Internationalization (I18n) so that your text is stored in your en.yml file and you can use the labels instead of strings:
# en.yml
en:
no_favorite: 'No favorite'
wine_and_cheese: 'Wine and Cheese'
burger_with_everything: 'Burger with everything'
# You can then translate the labels like this
I18n.t :no_favorite
I18n.t :wine_and_cheese
I18n.t :burger_with_everything
The next step would be to create some kind of hash or class that stores and translates the integer values for you. A simple array solution might look like this:
OPTIONS = [:no_favorite, :wine_and_cheese, :burger_with_everything]
You could then use the options like this:
selected_value = 1
I18n.t OPTIONS[selected_value] # => wine_and_cheese
OPTIONS.index :wine_and_cheese # => 1
Furthermore, if the selected option was a model value (say User#food_preference) you could define a function for displaying that user's food preference:
class User
OPTIONS = [:no_favorite, :wine_and_cheese, :burger_with_everything]
def display_food_preference
I18n.t OPTIONS[food_preference]
end
end
I'm not sure what you're trying to do here, but why not store the strings in the model. Sth like:
class User < ActiveRecord::Base
def favfood_description
"bla bla" if favfood == 0
end
end

Resources