Can I add params values to a hash? - ruby

I have a User model. I also have a form_for(#user...) form. This form spans 3 partials. In order for every partial to remember values I use the following command inside my create action in my UsersController:
session[:user_params].deep_merge!(params[:user]) if params[:user]
This way every partial adds params[:user] to session[:user_params]. I also have other form values stored inside the params hash which are not part of the User model. Is there a command which would allow me to add all single params values (not just the :user hash) to the session[:user_params] hash without adding every single value one by one like this:
session[:num_children] = params[:num_children] if params[:num_children]
...etc...

Try:
params.each {|key,value| session.deep_merge!(key=>value)}

Related

rails string substitution or similar solution in controller

I'm building a site with users in all 50 states. We need to display information for each user that is specific to their situation, e.g., the number of events they completed in that state. Each state's view (a partial) displays state-specific information and, therefore, relies upon state-specific calculations in a state-specific model. We'd like to do something similar to this:
##{user.state} = #{user.state.capitalize}.new(current_user)
in the users_controller instead of
#illinois = Illinois.new(current_user) if (#user.state == 'illinois')
.... [and the remaining 49 states]
#wisconsin = Wisconsin.new(current_user) if (#user.state == 'wisconsin')
to trigger the Illinois.rb model and, in turn, drive the view defined in the users_controller by
def user_state_view
#user = current_user
#events = Event.all
#illinois = Illinois.new(current_user) if (#user.state == 'illinois')
end
I'm struggling to find a better way to do this / refactor it. Thanks!
I would avoid dynamically defining instance variables if you can help it. It can be done with instance_variable_set but it's unnecessary. There's no reason you need to define the variable as #illinois instead of just #user_state or something like that. Here is one way to do it.
First make a static list of states:
def states
%{wisconsin arkansas new_york etc}
end
then make a dictionary which maps those states to their classes:
def state_classes
states.reduce({}) do |memo, state|
memo[state] = state.camelize.constantize
memo
end
end
# = { 'illinois' => Illinois, 'wisconsin' => Wisconsin, 'new_york' => NewYork, etc }
It's important that you hard-code a list of state identifiers somewhere, because it's not a good practice to pass arbitrary values to contantize.
Then instantiating the correct class is a breeze:
#user_state = state_classes[#user.state].new(current_user)
there are definitely other ways to do this (for example, it could be added on the model layer instead)

Putting Faker Gem Values to a Hash

I'm writing automated tests using Cucumber, Capybara, WebDriver, SitePrism, and Faker. I am new to this and need some help.
I have the following steps..
Given (/^I have created a new active product$/) do
#page = AdminProductCreationPage.new
#page.should be_displayed
#page.producttitle.set Faker::Name.title
#page.product_sku.set Faker::Number.number(8)
click #page.product_save
#page.should have_growl text: 'Save Successful.'
end
When (/^I navigate to that product detail page) do
pending
end
Then (/^All the data should match that which was initially entered$/) do
pending
end
In config/env_config.rb I have set up an empty hash...
Before do
# Empty container for easily sharing data between step definitions
#verify = {}
end
Now I want to hash the value generated by Faker in the Given step so I can validate it saved properly in the When step. I also want to enter the value generated by faker in the script below into a search field.
#page.producttitle.set Faker::Name.title
How do I push the values generated by faker to the #verify has?
How do I pull that value and insert it into a text field?
How do I pull that value to verify the save value equals the value generated by faker?
1. How do I push the values generated by faker to the #verify has?
A hash is simply a dictionary of key-value pairs, which you can set with hash[key] = value.
The key can be a string #verify['new_product_name'] = Faker::Name.title
The key can also be a symbol #verify[:new_product_name] = Faker::Name.title
Since the value you generate may be used multiple times within the step definition (once for storing it in the #verify hash, and once for setting the field value) I personally prefer to first store it in a local variable, and reference that where needed.
new_product_title = Faker::Name.title
#verify[:new_product_title] = new_product_title
2. How do I pull that value and insert it into a text field?
You can reference values by their key. So after you have stored the value in the hash, you could do this
#page.producttitle.set #verify[:new_product_name]
Or if you stored it in a local variable as suggested above, you would just do this
#page.producttitle.set new_product_name
3. How do I pull that value to verify the save value equals the value generated by faker?
Similarly, you can assert that a field value equals what you've stored in the hash. An example would be #page.producttitle.value.should == #verify[:new_product_name]
Putting this all together:
Given (/^I have created a new active product$/) do
#page = AdminProductCreationPage.new
#page.should be_displayed
# Create a new title
new_product_title = Faker::Name.title
# Store the title in the hash for verification
#verify[:new_product_title] = new_product_title
# Set the input value to our new title
#page.producttitle.set new_product_title
#page.product_sku.set Faker::Number.number(8)
click #page.product_save
#page.should have_growl text: 'Save Successful.'
end
When (/^I navigate to that product detail page) do
pending
end
Then (/^All the data should match that which was initially entered$/) do
#page.producttitle.value.should == #verify[:new_product_title]
end

Text input value as a number

I want input field value to be a number instead of string.
A simple scenario is you have 2 input fields and submit button on a page. When you click submit you should get sum of numbers keyed in both the input fields and not appended strings.
I tried using "number_field_tag" for input type=number but the value is still a String and not Fixnum what I want.
As Surya stated in his comment, what comes from the form fields is always a string. But you can do something like this in the controller action that processes the form (presuming you're using Rails):
def process_form
#result = params[:first_field].to_i + params[:second_field].to_i
end

Getting model value and generated ID from within simple_form custom input

I'm trying to make a custom input type with simple_form that will implement combobox-type functionality using jQuery-Autocomplete
. What I need to do is output a hidden field that will hold the ID of the value selected and a text field for the user to type in.
Here's what I have so far:
class ComboboxInput < SimpleForm::Inputs::Base
def input
html = #builder.hidden_field(attribute_name, input_html_options)
id = '' #what?
value = '' #what?
return "#{html}<input class='combobox-entry' data-id-input='#{id}' value='#{value}'".html_safe
end
end
I need to get the ID of the hidden field that simple_form is generating to place as an HTML attribute on the text entry to allow the JavaScript to "hook up" the two fields. I also need to get the value from the model to prepopulate the text input. How do I do this from within my custom input?
I'm looking for the id as well, but I did get the value:
def input
current_value = object.send("#{attribute_name}")
end
I just found a hokey id workaround:
html = #builder.hidden_field(attribute_name, input_html_options)
id = html.scan(/id="([^"]*)"/).first.first.to_s
I know it's a hack, but it does work. Since we don't have access directly to this type of resolution, it is likely to keep working even if the underlying id creation code changes.

how to find a hash key with one of the predefined names?

I have a hash with an arbitrary key:
{'GET': [1,2,3]}
or
{'POST': ['my data 0', 'my data 1']}
The hash is generated from JSON which is sent in the request body. There is just one key, or rather, I ignore any keys but one.
I want to find which key it is, and this is the code that I wrote:
items = data['GET'] || data['get'] || data['POST'] || data['post']
this does not look neat. If the number of keys that I want to process grows the expression will be long. I want it to be short. I am new to Ruby, is there a better way?
If you think it might grow, you may want to separate the HTTP methods from the finding of that method in the data:
methods = [:get, :post]
def find_method(data)
keys = methods.map{|m| [m.to_s.upcase, m.to_s]}.flatten
data.values_at(keys).first
end
You could just get the first value (assuming there's only one) like this:
item = data.values.first
You could use the Hash#values_at method.
http://www.ruby-doc.org/core-1.9.3/Hash.html#method-i-values_at
data.values_at('GET','get', 'POST','post').first

Resources