Rails render hash in views - ruby-on-rails

I am unable to render key value pairs from a hash.
Here is the hash
#the_object_pairs = { :building_permits => '#', :new_owners => '#'}
I have tried the following views
I've tried without raw
<%= raw #the_object_pairs.map do |key, value| %>
with
<h1>Hi</h1>
and I get #
when I try without raw and following inside the block
"<h1>"Hi</>".html_safe
I get
".html_safe "
".html_safe [" \"<div></div>\".html_safe\n", " \"<div></div>\".html_safe\n"]
I've tried several other combinations using the key value pairs with no luck at all. I've also tried each and each_pair instead of map.
Does anyone know how to properly render html when hashes are involved.

From what you wrote in your question, it is difficult to tell what data from the hash you want displayed in your view and where in your view you want it, but here are a few suggestions:
If you want to display a single item from your hash, just put something like this in your view:
<%= #the_object_pairs[:building_permits] %>
Or if you want to show all of the items in the hash in a vertical list, you can do:
<% #the_object_pairs.each do |key,value| %>
The key is: <%= key %>
The value is: <%= value %> <br />
<% end %>

Related

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.

Rails Loop Through Hash

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.

submit value of html table to variable in controller ruby

I have a table in view:
#view
<%= form_tag save_table_path do %>
<table>
<% #channel_name_body.values.max_by(&:size).size.times do |i| %>
<tr class="border">
<% #channel_name_body.values.map { |a| a[i] }.each do |value| %>
<td contenteditable class="border light_green"><%= value %></td>
<% end %>
</tr>
<% end %>
</table>
<%= submit_tag "save",:class => "btn btn-primary offset4" %>
<% end %>
I don't know what to do next to pass value of all cell in table to controller such as:
#controller
def save_table
#table=params[:table] #or #row1=params[:row1]... or #col1=params[:col1]....
end
Edit: I found way to solve this problem, it must use js.
I don't want to use js, what about if I change to <%= text_field_tag :cell, value %> how can I get value of all cell in table ?
I think you're getting confused with how to handle data in Rails (or any backend system)
HTML
HTML is a markup language; which means if you give it certain code, it will put various elements onto the page. The <table> tag is one of those elements, and has no bearing on the controller-side functionality of your app
Controller Params
HTML form params are directly related to the form (nothing else)
In Rails, you get the params hash ordered like this:
params[:form_name][:input_name]
Your Code
From what you've shown, it seems you have several parts missing
Firstly, you need input elements (to populate the params). Currently, you have:
<td contenteditable class="border light_green"><%= value %></td>
This does not create any params, as it's not an input element. It's just a value that's been outputted on the screen. What you'd need is something like:
<td contenteditable class="border light_green"><%= text_field_tag :cell, :value => value %></td>
By adding these inputs, you will give Rails the ability to populate the params hash with their values, which you can then access from your controller like this:
def save
#table = params[:form_name][:cell][0]
end
Hope this helps?
Try this:
<%= text_field_tag "table[cell#{index}]", value %>
On form submit it will give you values like params[:table][:cell1], params[:table][:cell2] and so on...
Hope this helps..

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.

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