Iterate over hashref Template Toolkit - template-toolkit

The data that I'm passing to the template is as follows:
This is the 'tickets' hashref used in the following foreach:
$VAR1 = {
'1234' => {'request_time' => '1405392890', 'id' => '1234'},
'9993' => {'request_time' => '1485035309', 'id' => '9993'}
};
I am doing the following:
[% FOREACH ticket IN tickets %]
<td>[% ticket.request_time %]</td>
<td>[% ticket.id %]</td>
[% END -%]
But this doesn't seem to display anything. Could someone point out where I'm wrong?

You also need to be careful that TT doesn't treat a numeric hash-key as an array-element reference. If there's a risk of confusion (or if you have a clash between hash-keys and vmethod names), then the vmethod item() is particularly useful:
[% FOREACH ticket IN tickets.keys.nsort %]
<td>[% tickets.item(ticket).request_time %]</td>
<td>[% ticket %]</td>
[% END -%]

I wasn't aware you had to use the 'keys' vmethod:
[% FOREACH ticket IN tickets.keys %]
<td>[% tickets.$ticket.request_time %]</td>
<td>[% tickets.$ticket.id %]</td>
[% END -%]

Related

Getting {", value= "=>"on"} as a paramater when I want an Object's id

I have a program that is supposed to simulate a delivery POS. A Delivery Object belongs_to a Meal Object, which has_many items. The form renders a bunch of items with a checkbox next to each item using helper methods like this...
#inside the app/models/item.rb file
def self.meal_field_maker(foods)
rStr = ""
foods.each do | sel |
rStr += "<p><input type= 'checkbox' name= 'meal[items][], value= '#{sel.id}'> #{sel.show} </p>"
end
return rStr
end
#inside the app/helpers/application_helper.rb file
def the_new_meal_form
foodgroups = Item.get_foodgroups #Gets each food group
rStr = ""
foodgroups.each do | sel |
rStr+= "\n<h3>#{sel}</h3>" #Adds the name of each Food Group as a header before checkboxes
groupedFoods = Item.list_items_of_group(sel) #Gets every item of a food group
rStr += Item.meal_field_maker(groupedFoods) #makes a checkbox input tag for each item in groupedFoods
end
return (rStr)
end
And this all renders properly in the form which looks like this...
<form method= "post" action= "new_user_delivery">
<input type= "hidden" name= "delivery[user]" value= <%= #user.id %>
<%= user_delivery_address_field(session).html_safe %>
<p>(Optional) Meal Name: <input type= "text" name="delivery[meal][name]"></p>
<p>----------------------------------------------------</p>
<%= the_new_meal_form.html_safe %>
<p>----------------------------------------------------</p>
<p>Proceed to Payment <input type= "submit" value= "Proceed">
</form>
And It looks like it all works perfectly, but on the next action the params look like this...
<ActionController::Parameters {"delivery"=>{"user"=>"11", "address"=>"98 Linden Ave", "meal"=>{"name"=>"FirstMeal"}}, "meal"=>{"items"=>[{", value= "=>"on"}, {", value= "=>"on"}, {", value= "=>"on"}, {", value= "=>"on"}, {", value= "=>"on"}]}, "controller"=>"deliveries", "action"=>"payment_options", "id"=>"11"} permitted: false>
The issue here is clearly that for every item I select, I just get {", value= "=>"on"}, which of course gives me no indication which Item Objects were chose, as you see this is ~supposed~ to return the Item's ID as the parameter value. How do I fix this?
Your line here:
rStr += "<p><input type= 'checkbox' name= 'meal[items][], value= '#{sel.id}'> #{sel.show} </p>"
is missing a single quote after 'meal[items][]. Also make sure you don't have spaces immediately after equals signs:
rStr += "<p><input type='checkbox' name='meal[items][]', value='#{sel.id}'> #{sel.show} </p>"
I would say that it's generally a code smell if you have HTML building code inside your model. It's usually better to keep those in views or helpers, but that's outside the scope of this question.

Test for consecutive HTML elements in Rails view

I wish to run a test* to check for presence of something like this:
<tr>
<td> name </td> <td> date </td>
</tr>
Code, such as below:
assert_select "tr" do
assert_select "td", name
assert_select "td", date
end
looks plausible, but is not correct, as the below for example (which is not the match required) would also pass:
<tr>
<td> name </td>
</tr>
<tr>
<td> date </td>
</tr>
I’m struggling to see how this should be approached from the documentation of assert_select.
Thank you
Daniel
within a default Rails integration test (I believe this means MiniTest)
I ended up using a regexs on the result of a css_select, which seems a bit inelegant, but worked for my purposes. If there is a better way I'd be interested to hear it. I used something like this:
pars = css_select "tr"
regexs = /<td>#{name}<\/td>.*<td>#{date}<\/td>/m
match = false
pars.each { |i| if i.to_s =~ regexs then match = true end}
assert match

Analog of template toolkit block-include in erb rails

What is the analog of template toolkit block-include in erb rails?
Or how to translate this code to rails erb (only one single file):
[% BLOCK hello %]
Hello [% var %]!
[% END %]
[% INCLUDE hello var='World' %]
result:
Hello World!

selected value of f..select lost after page refresh in ruby on rails

I have a dropdown in ruby on rails i.e below:
<table>
<tr>
<td align="center">
<%= f.select(:Interest,options_from_collection_for_select(#students, "id", "student_mentor_subjects"), {},:id => "DDL_Students", :style => "width:160px;") %>
</td>
</tr>
</table>
And students is a table that are populating f.select and below is the schema of students table:
id | student_mentor_subjects
1 | ijk
2 | mno
3 | pqr
And when I select a value from above f.select and click on search button then page is refresh and the selected value is lost, How could I retain the selected value of f.select after page refresh.
Kindly help me, Thanks.
From the api:
http://api.rubyonrails.org/classes/ActionView/Helpers/FormOptionsHelper.html#method-i-options_from_collection_for_select
options_from_collection_for_select(collection, value_method, text_method, selected = nil)
The fourth argument to options_from_collection_for_select is the default value. In your case you need to set it from params, then fall back to a specific default if there's nothing in params for it (which would be the case when you load the page for the first time).
I don't know which value to read from params as you've not posted the rest of the form, but if you look in your log you should see which value you want to read. So, it might be something like
<%= f.select(:Interest,options_from_collection_for_select(#students, "id", "student_mentor_subjects", params[:search][:interest] || #students.first.id), {},:id => "DDL_Students", :style => "width:160px;") %>

Creating a grouped output using Template toolkit

I have a datafile
city : name
London : John
London : George
Paris : Jean
And I would like output
London
John
George
Paris
Jean
I feel i want something like
[% USE namelist = datafile( 'namelist.txt' ) %]
[% FOREACH city = unique namelist.city ??? %]
[% city %]
[% FOREACH name =???? %]
[% name %]
[%END %]
[%END %]
It is probably best to do this kind of data munging in your controller. Template toolkit's job is really to lay things out and make them pretty, not do "calculations".
What you want is something more like:
[% SET list = formatter.group_them('namelist.txt') %]
[% FOREACH item IN list %]
[% item.key %]
[% FOREACH name IN item.value %]
[% name %]
[% END %]
[% END %]
It is possible to do what you want in a variety of ways. You can use VMethods http://template-toolkit.org/docs/manual/VMethods.html to split, create an array, split again, build a hash:
[% data = INSERT 'namelist.txt' %]
[% lines = data.split("\n") %]\
[% list = {} %]
[% FOREACH line IN lines %]
[% pair = line.split(': ') %]
[% city = pair.0; name = pair.1; list.city.push(name) %]
[% END %]
OK, I have to admit, I would be mortified to see this in a template I inherited. But sometimes we do things that mortify others for a good reason... at the time... :-)
A slightly better approach is to insert
[% RAWPERL %]
block. At least then, you are admitting, you have code within the template and doing the operations in a natural and efficient way.

Resources