Rails 3 view partial passing a block - ruby

I'd like to create a partial as follow:
%nav.tab_nav
%ul
%li.active
%a
Variable1
%li
%a
Variable2
%li
%a
Variable...n
Where variable1 variable2 etc exist, but the number of variables change, so I could traverse an array of arguments or something, but I don't know how to pass this array to the partial. Is there a way to pass a block or similar ?

Passing locals for partial:
= render :partial => "tabs", :locals => { :items => ["foo", "bar", "baz"] }
Looping part:
%nav
%ul
- items.each do |item|
%li
%a= item
http://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables

Related

How to pass a hash object to a HAML tag

Please consider this example:
- user_links_params = _user_link_params(current_user)
%a{ :'data-msgstore-path' => user_links_params[:'data-msgstore-path'],
:'data-user_id' => user_links_params[:'data-user_id'],
:class => user_links_params[:class],
}
/ too many html tags and stuff to fit in a simple link_to
I would be nice to fit all this in a simple statement like the following:
%a[_user_link_params(current_user)]
/ too many html tags and stuff to fit in a simple link_to
Yes, it's possible, and you were close:
%a{_user_link_params(current_user)}
From the HAML reference:
For example, if you defined
def hash1
{:bread => 'white', :filling => 'peanut butter and jelly'}
end
def hash2
{:bread => 'whole wheat'}
end
then %sandwich{hash1, hash2, :delicious => true}/ would compile to:
<sandwich bread='whole wheat' delicious='true' filling='peanut butter and jelly' />

`includes?` in an array that may not be assigned

Is there a one-line way to use include if the array it's searching may not be assigned?
I've tried a lot of variants of
(foo || []).include?(:bar)
but without success
If foo really is nil, as opposed to undefined, then (foo || []).include?(:bar) will do what you want, however if foo is not set to anything yet, then you will get a NameError so we can check for that with a longer oneliner...
defined?(foo) ? (foo || []).include?(:bar) : false
(foo ||= []).include?(:bar)
That will do the trick.
Maybe this?
foo.includes? :bar if foo
Since you are using partials, put this on the top of your partial:
<% foo = [] unless local_assigns.has_key?(:foo) # for Arrays %>
<% foo = {} unless local_assigns.has_key?(:foo) # for Hashes %>
<% foo = "" unless local_assigns.has_key?(:foo) # for Strings %>
etc.
This is the proper way of checking if a variable used in a partial has been set at all.
In the views using the foo partial:
<% render :partial => "foo", :locals {:a => 1, :foo => [2, 3, 4]} %>
<% render :partial => "foo", :locals {:a => 1} %>
In the first case, the foo variable will be [2,3,4] in the foo partial.
In the second case, the foo variable will not be put in local_assigns and will thus be given a default value as per the code above.

Ruby: Loop through hash and check if a key exists to determine markup and data to be displayed

This is my first time working with Ruby, so I may be approaching this incorrectly.
I am trying to go through a hash to display it's contents. As I'm going through the hash I'll need to test if a key exists, like city. If city doesn't exist then it shouldn't display the address. This is where I've started with building my hash:
# app.rb
set :haml, :format => :html5
get "/" do
#users = Hash[
[["name", "bill"], ["city", "nyc"], ["address", "street"]],
[["name", "ted"], ["city", "denver"]],
[["name", "sam"], ["address", "road"]]
]
haml :index
end
And this is how I am looping through the hash:
# layout.haml
- #users.each do |user|
- user.each do |u|
- u.each do |b|
= b
Once I get to b it will display all of the content like so:
["name", "bill"]
["city", "nyc"]
["address", "street"]
["name", "ted"]
["city", "denver"]
In the loop, how can I display the name as well as check to see if the address exists for each user to determine if the city should be displayed as well as any markup that may need to be added? It would ideally display something like:
<p>bill, <span class="address">nyc, street</span></p>
<p>ted</p>
<p>sam, <span class="address">road</span></p>
Am I creating the Hash properly to do it this way?
Instead of what you are trying to do with nested arrays inside a hash, it would be better to have an array that contains user hashes:
#users = [
{ :name => 'bill', :city => 'city', :address => 'street' },
{ :name => 'ted', :city => 'denver' },
{ :name => 'sam', :address => 'road' }
]
With that, you can do something like this:
- #users.each do |user|
= user[:name]
- if user.has_key?(:address) && user.has_key?(:city)
= "#{user[:address]}, #{user[:city]}"
- elsif user.has_key?(:address)
= "#{user[:address]}"

How can I get all the checked items from a submitted form with sinatra's params?

I'm running Sinatra 1.0 with HAML, my form has a number of checkboxes, for example books I like, and you would select all the books you want. The checkbox name is "books".
In sinatra params['books'] there should be an array of all the books that were checked, but it only has the last item that was checked, not an array.
How can I get all the checked items?
HAML:
%form{:action => "/test", :method => 'post'}
%input{:name=>'check',:type=>'checkbox',:value=>'item1'} item 1
%input{:name=>'check',:type=>'checkbox',:value=>'item2'} item 2
%input{:name=>'check',:type=>'checkbox',:value=>'item3'} item 3
%input{:type => "submit", :value => "send", :class => "button"}
Sinatra get method
post '/test' do
puts params['check'] #should be an array but is last item checked
end
Very close, but do not but numbers in the arrays
%form{:action => "/test", :method => 'post'}
%input{:name=>'check[]',:type=>'checkbox',:value=>'item1'} item 1
%input{:name=>'check[]',:type=>'checkbox',:value=>'item2'} item 2
%input{:name=>'check[]',:type=>'checkbox',:value=>'item3'} item 3
Now,
post '/test' do
puts params['check'] #puts an array of what was checked to stdout
end
Wouldn't that output a bunch of checkboxes with the same name? If so, params['check'] is probably getting replaced with each new checkbox.
Try naming each one something different. If you really want it in an array, try hacking the names:
%input{:name=>'check[1]',:type=>'checkbox',:value=>'item1'} item 1
%input{:name=>'check[2]',:type=>'checkbox',:value=>'item2'} item 2
%input{:name=>'check[3]',:type=>'checkbox',:value=>'item3'} item 3
Try
%input{:type => "checkbox", :value => "1", :name => "checkbox[]", :id => "id1"} Chk1
%input{:type => "checkbox", :value => "2", :name => "checkbox[]", :id => "id2"} Chk2
%input{:type => "checkbox", :value => "3", :name => "checkbox[]", :id => "id3"} Chk3
Then in the rails or sinatra
puts params[:checkbox]
Then you can see the checked items.

ruby - if string is not contained within an array

I only want to output one anchor here. If the current_page is in the array I get two (.html and -nf.html). If it is not in the array I get as many anchors as there are items in the array.
I am using StaticMatic.
- if page_options[:current_index] < page_options[:total_index] && page_options[:current_index] > 0
// loop through the pre-flash array and if current page matches, add -nf
- page_options[:pre_flash] = ['string_one-nf', 'string_two-nf', 'string_three-nf']
- page_options[:pre_flash].each do |each_string|
- if current_page.include? each_string
%li
%a{ :href => "page#{page_options[:current_index]}-nf.html", :class => "next" }
Next
- else
%li
%a{ :href => "page#{page_options[:current_index]}.html", :class => "next" }
Next
unless current_page.include? the_string
Edit:
You could break the each-loop if you want your first finding to be the only one.
But now this looks a little bit weird, because you are iterating over an array
and breaking after the first element no matter what happens.
Am I addressing your problem at all?
options[:pre_flash] = ['string_one-nf', 'string_two-nf', 'string_three-nf']
page_options[:pre_flash].each do |each_string|
if current_page.include? each_string
%li
%a{ :href => "page#{page_options[:current_index]}-nf.html", :class => "next" }
# This is the last ancor
break
else
%li
%a{ :href => "page#{page_options[:current_index]}.html", :class => "next" }
# This is the last ancor
break
end
end
Okay, so I think we're checking that none of page_options[:current_index] are substrings of current_page.
if page_options[:current_index] < page_options[:total_index] && page_options[:current_index] > 0
found_item = false
// loop through the pre-flash array and if current page matches, add -nf
- page_options[:pre_flash] = ['string_one-nf', 'string_two-nf', 'string_three-nf']
- page_options[:pre_flash].each do |each_string|
- if current_page.include? each_string
found_item = true
%li
%a{ :href => "page#{page_options[:current_index]}-nf.html", :class => "next" }
Next
# do whatever you need to get out of the staticmatic block...
- if !found_item
%li
%a{ :href => "page#{page_options[:current_index]}.html", :class => "next" }
Sorry - I misunderstood what you were doing... thought you were doing an include? on an array but it was a string... :-)

Resources