View helper to split list in two column - ruby-on-rails

I have a little problem.
I'm rendering a definition list in my haml view. Here is the code.
.col
- #product.data.each do |features_group_id, features_group|
.data-group
%h3= features_group["name"]
%dl
- features_group['features'].each do |id, hash|
- if #product.product_category.show_feature_ids.include?(id)
%span.data-wrap
%dt
= hash['name']
%dd
= hash['value']
I must split this list in two column.
I must take product.data.count/2 and show the two blocks in two column
.col
- #product.data_batch1.each do |features_group_id, features_group|
.data-group
%h3= features_group["name"]
%dl
- features_group['features'].each do |id, hash|
- if #product.product_category.show_feature_ids.include?(id)
%span.data-wrap
%dt
= hash['name']
%dd
= hash['value']
.col
- #product.data_batch2.each do |features_group_id, features_group|
.data-group
%h3= features_group["name"]
%dl
- features_group['features'].each do |id, hash|
- if #product.product_category.show_feature_ids.include?(id)
%span.data-wrap
%dt
= hash['name']
%dd
= hash['value']
Any easy solution to do this?

You can use in_groups_of, given that #product.data is or acts as an Array.
From your code:
- #product.data.in_groups_of(2, false).each do |group|
.col
- group.each do |features_group_id, features_group|
.data-group
%h3= features_group["name"]
%dl
- features_group['features'].each do |id, hash|
- if #product.product_category.show_feature_ids.include?(id)
%span.data-wrap
%dt
= hash['name']
%dd
= hash['value']
There is even a Railscast on this! :-)

Related

Create a like method for filter query on Rails, smart_listing gem

I want to filter the content of a table who i created with smart_listing gem
For the unknown, SmartListing also known as smart_listing is a Ruby Gem that provides a tools to create lists on your Rails app
I can use the pagination but the filter still not working
Link to smart_listing documentation for Controls (filtering) documentation section
In the docs says that:
# Apply the search control filter.
# Note: `like` method here is not built-in Rails scope. You need to define it by yourself.
users_scope = users_scope.like(params[:filter]) if params[:filter]
This is my code, how i can make runs the filter? I have this on the controller
if !current_user.current_organization.import_columns.nil?
#import_contacts = UserImport.where(organization_id: current_user.current_organization.id)
#import_contacts_column_filter = current_user.current_organization.import_columns.split(/,/)
contacts_import_scope = #import_contacts
contacts_import_scope = contacts_import_scope.like(params[:filter]) if params[:filter]
#contacts_import_scope = begin_of_association_chain.order('active DESC')
#contacts_import_scope = contacts_import_scope.imported_users_filter(params[:filter].strip) if params[:filter]
#import_contacts_listing = smart_listing_create(
:import_contacts,
contacts_import_scope,
partial: 'contacts/listing_import',
default_sort: {created_at: "desc"}
)
end
This on the Views
index.html.slim
.tab-content
- if #import_contacts.any?
.search-wrapper.pull-right
= smart_listing_controls_for(:import_contacts) do
span.btn.pull-right
i.fa.fa-search
.filter.input-append.pull-right
= text_field_tag :filter, '', class: 'search', placeholder: "#{t('commons.filters.search_pending_petition_contacts')}", autocomplete: 'off'
_listing_import.slim
- unless smart_listing.empty?
.pending_contacts_table.table-responsive
table class="table-striped table-list" style="width: 100%; background-color: #FAFBFD;"
thead
tr
- #import_contacts_column_filter.each do |column|
th.name.col-sm-2 = smart_listing.sortable "#{column}", "#{column}"
th.name.col-sm-2 Añadir
tbody
- smart_listing.collection.each do |user_imported|
tr
- #import_contacts_column_filter.each do |field|
td = "#{user_imported.send(field)}"
td
- if User.exists?(email: user_imported.email)
p Ya añadido
- else
- last_name = "#{user_imported.surname1}"+"#{user_imported.surname2}"
= link_to new_organization_customer_path(name: user_imported.name, last_name: last_name, email: user_imported.email, tmp_pass: user_imported.tmp_pass), class: 'btn btn-success' do
i class='fa fa-plus-square'
= page_entries_info smart_listing.collection
= smart_listing.paginate
- else
How we define the doc's .like method?
As i wrote on the code and left commented, before i tried to write in this way also without results.
#contacts_import_scope = contacts_import_scope.imported_users_filter(params[:filter].strip) if params[:filter]
Solved!
issue was with the ImportsController, must be defined on it and not on ContactsController.
also controller finally looks as this
def load_import_contacts
#import_contacts_column_filter = current_user.current_organization.import_columns.split(/,/)
#import_contacts = UserImport.where(organization_id: current_user.current_organization.id)
#import_contacts = #import_contacts.where("name Like ? OR surname1 LIKE ? OR surname2 LIKE ? OR reference_number LIKE ? OR email LIKE ? OR mutua LIKE ?", "%#{params[:filter]}%","%#{params[:filter]}%", "%#{params[:filter]}%", "%#{params[:filter]}%","%#{params[:filter]}%", "%#{params[:filter]}%") if params[:filter]
#import_contacts_listing = smart_listing_create(
:import_contacts,
#import_contacts,
And _listing_import.slim...
#import_contacts = #import_contacts.where("name Like ? OR surname1 LIKE ? OR surname2 LIKE ? OR reference_number LIKE ? OR email LIKE ? OR mutua LIKE ?", "%#{params[:filter]}%","%#{params[:filter]}%", "%#{params[:filter]}%", "%#{params[:filter]}%","%#{params[:filter]}%", "%#{params[:filter]}%") if params[:filter]
Finally, filter and pagination works!

Why is ruby's '.each' giving different results to using 'for'?

I am trying to switch a for x in y loop to a each_with_index. First, I am trying to switch from for to each. The code before is
...
- row_bg_color_group = 'row_color_group_1'
- for link in #links
- construct_hyperlink(link.url_address, link.alt_text)
- if link.group.group_name != (current_group ||= '')
- display_group = current_group = link.group.group_name
- row_bg_color_group = rotate_rows_color_group
- else
- display_group = ''
%tr{:class => "#{row_bg_color_group}"}
%td
= link_to display_group, link.group, {"title" => link.group.group_description}
%td
%span#mainLink
= sanitize #address_url
%td= link.version_number
....
and rotate_rows_color_group is a helper in app/helpers. The code is
def rotate_rows_color_group
if session[:group_shading] == 'true' || params[:show]
cycle('row_color_group_1 color_group_1', 'row_color_group_2 color_group_2', 'row_color_group_3 color_group_3')
else
cycle('row_color_group_1', 'row_color_group_2', 'row_color_group_3')
end
end
The initial change I made is just to switch
- for link in #links
to be
- #links.each do |link|
This is changing my view from
to
The group name gets repeated. Is it a scope issue?
Since .each uses a block, any variable declared within it will be re-declared each time it is entered.
To avoid this, simply declare current_group outside the block:
...
- row_bg_color_group = 'row_color_group_1'
- current_group = ''
- #links.each do |link|
- construct_hyperlink(link.url_address, link.alt_text)
- if link.group.group_name != current_group
- display_group = current_group = link.group.group_name
- row_bg_color_group = rotate_rows_color_group
- else
- display_group = ''
%tr{:class => "#{row_bg_color_group}"}
%td
= link_to display_group, link.group, {"title" => link.group.group_description}
%td
%span#mainLink
= sanitize #address_url
%td= link.version_number
....

Order alphabetically and group by first letter

I currently have the following code:
- #alpha = Glossary.find(:all, :order =>"title ASC").group_by{|u| u.title[0]}
- #glossary = Glossary.find(:all, :order =>"title ASC")
- #alpha.each do|a|
%h1= a[0]
- #glossary.each do |g|
%p display stuff
This displays all of the glossary terms under each letter rather than only the ones that begin with the letter.. I've tried a few things but I'm not sure how to select the right thing.
You should be able to do everything with your #alpha instance variable, since you're using group_by:
- #alpha = Glossary.find(:all, :order =>"title ASC").group_by{|u| u.title[0]}
- #alpha.each do |alpha, glossary_array|
%h1= alpha
- glossary_array.each do |item|
%p= item
You're close. I think you just want to do
- #alpha = Glossary.order("title ASC").group_by{|u| u.title[0]}
- #alpha.each do |letter, items|
%h1= letter
- items.each do |item|
%p= item

Get Value out of object Hash in Rails

I have the following code:
def analytics
#user_registrations = User.count(:conditions => ["created_at >= ?", 30.days.ago.to_date], group: "date(created_at)")
#daily_count = []
30.times do |day|
#daily_count << [Date.today - day, #user_registrations['#{Date.today - day}']]
end
end
which when run with: <%= simple_format #user_registrations.to_yaml %> produces:
--- !omap
- '2012-08-23': 11
I want to get the 11 value out and put that in my daily_count array.
How can I do that?
update:
<%= simple_format #user_registrations.to_yaml %>
<%= simple_format #daily_count.to_yaml %>
results in the image:
Just replace:
#daily_count << [Date.today - day, #user_registrations['#{Date.today - day}']]
with:
#daily_count << [Date.today - day, #user_registrations["#{Date.today - day}"] || 0]
Single quotes will cause the #{} escape syntax to be treated as a literal, double quotes cause it to be eval'ed.

haml conditional if/else indentation

I have a situation where I want to add a class to a div tag only when the count is greater than 0
Example:
- #color.shades.each_with_index do |shade, index|
- if index == 0
#shades
- else
#shades.horizontalLine.second
%h3 something
%dl
%dt some
%dd some1
In this example I want everything starting from %h3 to come under either #shades or #shades.horizontalLine.second depending on however those if and else statements evaluate.
work around is:
- #color.shades.each_with_index do |shade, index|
- if index == 0
#shades
%h3 something
%dl
%dt some
%dd some1
- else
#shades.horizontalLine.second
%h3 something
%dl
%dt some
%dd some1
but here I have to repeat code
I'm stumped at how to do this in rails without repeating the code starting from %h3 for both the divs.
You can set the class to a variable holding the class names based on the index to DRY it up:
- #color.shades.each_with_index do |shade, index|
- shade_classes = index == 0 ? '' : 'horizontalLine second'
#shades{ :class => shade_classes }
%h3 something
%dl
%dt some
%dd some1

Resources