Rails Loop Through Hash - ruby-on-rails

A really simple question but I just can't seem to get it working.
There is only one Property included below but there could be more than one within Properties. How can I iterate through this hash and display just the Name of each Property?
{"GetPropertiesResponse"=>{"Properties"=>{"Property"=>{"Breakfast"=>"IN", "Country"=>"GB", "Currency"=>"GBP", "Id"=>"1834", "Name"=>"Hotel Name"}}}}
I've tried this in my view:
<% #json['GetPropertiesResponse']['Properties']['Property'].each do |property| %>
<%= property['Name'] %>
<% end %>
I'm getting this error:
no implicit conversion of String into Integer

If you are saying there might be more than one property hash then this should work:
<% #json['GetPropertiesResponse']['Properties'].each do |property, value| %>
<%= value['Name'] %>
<% end %>

I would use #each_value on this hash since you don't appear to be using the keys
<% #json['GetPropertiesResponse']['Properties'].each_value do |value| %>
<%= value['Name'] %>
<% end %>
Should work. Note that the second line is <%= value['Name'] %> and not <%= property['Name'] %>
P.S. On a different note, I don't know why you're using the key "Property" inside of your Properties hash. That just seems like a good way to confuse yourself in exactly this way. Your keys within the Properties hash should be something unique to the property they describe. Since each will be a property, the string "Property" doesn't help describe or differentiate.

Related

Ruby on Rails: Store array value in variable and use as string

I'm in the process of refactoring some code. I'm trying to use arrays in my view as part of a for loop that makes columns in a table.
I have defined the arrays in my controller:
subjects_controller.rb
def index
...
#CRFS_TO_VIEW = [Baseline, TreatmentCompletion]
#CRF_PATH = {Baseline => 'baseline_path', TreatmentCompletion => tc_path}
end
So my goal; as the function iterates over #CRFS_TO_VIEW, the correct path is selected from #CRF_PATH and appended to the link_to function.
indext.html.erb
<% #CRFS_TO_VIEW.each do |crf| %>
<% path = #CRF_PATH[crf] %>
<%= link_to "edit", path(crf.where(subject_id: sub.subject_id).first %>
<% end %>
I also tried :
<%= link_to "edit", #CRF_PATH[crf](crf.where(subject_id: sub.subject_id).first %>
Which didn't work. I feel I must be getting close, any help or insight would be greatly appreciated.
Thanks.
A few things:
a. You should save yourself some time and loop through the dictionary instead of the array:
<% #CRF_PATH.each do |crf, path| %>
...
<% end %>
b. You are getting a string from the loop - you can invoke the equivalent method with send:
<%= send(path, ...) %>
c. You can simplify your retrieval of the objects using:
crf.find_by(subject_id: sub.subject_id)
That said - this seems like a pretty bad way of doing things. I'd recommend instead adding a view helper:
def crf_path(crf)
case crf
when Baseline then baseline_path(crf)
...
end
With something like this you could use (notice changed the find_by to find_by! for safety as well):
<% #CRFS_TO_VIEW.each do |crf| %>
<%= link_to "edit", crf_path(crf.find_by!(subject_id: sub.subject_id) %>
<% end %>
Finally instance variables should NOT be named upper case. If you want to use a constant define it as a constant (otherwise use lower case names).

passing a hash to a route in rails

In the preview action in my controller, I have
#models = Model.all
In the view, Im trying to loop through all the models, draw out their associated images, and use those to link_to their own profiles.
<% #models.each do |m| %>
<div> <%= link_to(image_tag (m.avatar.url(:thumb)), model_path())%> </div>
<% end %>
I need to pass in the id of each model to the route. Using m.id doesn't work because the route is expecting a hash.
Not entirely sure how to do this. Other posts on SO refer to unsaved instances and such, which aren't really relevant to this.
Try changing your view code from this:
<% #models.each do |m| %>
<div> <%= link_to(image_tag (m.avatar.url(:thumb)), model_path())%> </div>
<% end %>
To:
<% #models.each do |m| %>
<div> <%= link_to(image_tag(m.avatar.url(:thumb)), model_path(m))%> </div>
<% end %>
As usual the error might be in a completely different place - your brackets.
model_path can accept both list of attributes and a hash. Most likely you think it is expecting a hash due to the error message (which you should include in the question). In fact however, you are passing the path to the image_tag, not to the link_to:
link_to(image_tag (m.avatar.url(:thumb)), model_path())
is parsed as
link_to( image_tag(m.avatar.url(:thumb), model_path()) )
While:
link_to(image_tag (m.avatar.url(:thumb)), model_path())
is parsed as
link_to( image_tag(m.avatar.url(:thumb)), model_path() )
This space between a method name and a bracket is a silent killer. It is a image_tag which is expecting a hash in a second argument. :)
That being said - it will still not work, but you should get a different problem now.

get specific values from rails array

I think I have a correct array going for rails?
#lv = {'apple' => ['tags', 'red'], 'name' => ['more tags', 'taggers']}
I was wondering how I can display certain parts through a loop. For instance, how would I only display apple and name?
<% #lv.each do |me| %>
<%= me %>
<% end %>
This just displays the whole #lv message, and doesn't only display apple and name. And then I'd like to be able to get only the tagged values of specific ones, so say if I need to get tagged value of apple, it should only display tags and red How do I do this with rails?
Thanks!
Your #lv variable is a hash, so using .each will only give you a combined key-value pair as the block parameter (that's what me ends up being). Instead, use each_pair; that way you can get separated variables for the keys and the values. Like so:
<% #lv.each_pair do |key, value| %>
<%= key %>
<% end %>
Edit
This is in response to your comment in the question as well. The key will end up being just the apple, or name, part of your hash. The value parameter is whatever is pointed to by the key, which in this case is the actual array of items (which I think is what you're calling tags). For example, your hash contains two key-value pairs, and as we iterate over them, in the first loop key = apple, and value=['tags', 'red']. To output that array of values, you could do it a couple of different ways:
Loop over the tag array
<% #lv.each_pair do |key, value| %>
<%= key %>
<%= value.each do |tag| %>
<%= tag %>
<%= end %>
<% end %>
As a comma separated string:
....looping code
<%= value.join(", ") %>
Or just spit it out as-is in array notation:
....looping code
<%= value %>
Or if you just wanted a specific element in the value array, then yes you can just do value[0], or value[1]...etc.
Let me know whether that is not what you are asking.

How to retrieve the hash values in the views in rails

I have an action in the controller:
def user_detail
#user_detail = UserDetail.find_by_id(11)
end
And in the view:
<%= #user_detail -%> // displays me like #
I am trying to retrieve the contents of #user_detail: actually the hash contains {:empid=>"11111", :prjtname=>"aaaaa", :prjtrole=>"Developer"}
How do I display the user detail's empid and other values?
Since I know what question you asked earlier, I think this is the syntax you actually want to use:
<%= #user_detail.additional_info[:empid] %>
Unless of course you renamed the name of the hash :)
Another approach, if you want all the content from the hash but the keys varies from each record, you could loop through them like this:
<% #user_detail.additional_info.each_pair do |key, value| %>
<p>Key: <%= key %> Value: <%= value %></p>
<% end %>
To get simple debug output like the example you posted, this will handle it:
<%= #user_detail.inspect %>
try this <%= #user_detail.emplid %> <%= #user_detail.prjtname %> <%= #user_detail.prjtr %>
More of an extraction from #dln's answer
try using
<%= #user_detail[:emplid] %>
<%= #user_detail[:prjtname] %>
<%= #user_detail[:prjtr] %>
Hope this solves your prob

Rails 'params' variable

In reference to this
I've created a question in a webform like this:
<div class="form_row">
<label for="features[]">Features:</label>
<% [ 'scenarios', 'role_profiles', 'private_messages', 'polls' ].each do |feature| %>
<br><%= check_box_tag 'features[]', feature,
(params[:features] || {}).include?(feature) %>
<% end %>
</div>
So if scenarios and private_messages gets checked and I print out params[:features] I will get:
scenariosprivate_messages
I was wondering how would I be able to obtain scenarios and private_messages separately from params. Is the mapping params[:features] = "scenariosprivate_messages" or is it really params[features] = ["scenarios", "private_messages"] ? If it's the latter how can I loop through them?
I write in my view:
<%= params[:features].each {|param|
param.capitalize
} %>
and I still just get scenariosprivate_messages printed.
Try this instead:
<% params[:features].each do |param| %>
<%= param.capitalize %>
<% end %>
The problem with your original solution is that you're printing out the result of the block, which is the array itself, rather than printing out each element of the array.
You shouldn't be using params in your views. You're best off assigning params[:features] to an instance variable in your controller and then iterating over that in your view.
But to answer your question, you're putting the equals sign for output in the wrong place. You want to output each element of the array individually instead of outputting the result of the loop.
You must use humanize:
<% params[:features].each do |param| %>
<%= param.humanize %>
<% end %>
According to this blog post you should be able to access them individually as params[:features]['scenarios'] etc. Looping should just work like with all other arrays -- eg
params[:features].each { |param|
# do something with param
}

Resources