<div class="row">
<% #group.each do |j| %>
<% #group.each_with_index do |i, index| %>
<% if j.category_id == i.category_id %>
<%= j.category_id%>
<%= j.title %>
<% break %>
<% end %>
<% end %>
<% end %>
</div>
This is the result:
1 Ultimo de ultimo 1 Benza Comedia 1 Lazo Comedia 1 Juans comedia 1 Primer Titulo Comedia
2 acc last 2 Acc Benza 2 Juans Acc 2 Primer titulo Accion
3 terr last 3 Juans terr 3 Terror tittle
4 Juans rom 4 Romance tittle
I only want the result to be the first find.
I want it to only be: 1 Ultimo de ultimo, 2 acc last, 3 terr last and 4 Juans rom.
You can try grouping it first
<div class="row">
<% #group.group_by { |g| g.category_id }.each_with_index do |(key, val), index| %>
<%= key %>
<%= val.first.title %>
<% end %>
</div>
I’m having trouble with ordering my houses. I have a houses that belong_to category (category has_many houses) and I want to order the houses on the index based on their category_id, but whatever I try it doesn’t seem to change the order. It’s a mystery to me. Maybe you could help me out?
class HousesController < ApplicationController
skip_before_action :authenticate_user!, only: [:index, :show]
before_action :set_house, only: [ :show, :edit, :update, :destroy, :inquiry ]
def index
# byebug
#houses = policy_scope(House).order(:name)
#houses = params.has_key?(:h) ? index_result(#houses) : #houses
# split_categories(#houses)
end
def index_result(houses)
# byebug
wall_thickness = params[:h].to_i
if wall_thickness == 1
houses.order(:name)
render "results_index_all"
elsif wall_thickness == 28 || 40
houses = houses.where(:wall => wall_thickness)
houses.order(:name)
render "results_index"
else
end
end
def split_categories(houses)
# #houses_1 = #houses.where(price_cents: 0...260000)
# #houses_2 = #houses.where(price_cents: 260000..1000000)
# byebug
category = Category.find_by(id: params[:category])
houses = #category.present? ? category.houses.order(price_cents: :asc) : houses
end
def show
end
def new
#house = House.new
authorize #house
end
def create
#house = House.new(house_params)
#house.user = current_user
authorize #house
if #house.save
redirect_to house_path(#house)
else
render :new
end
end
def edit
end
def update
if #house.update(house_params)
redirect_to house_path(#house)
else
render :edit
end
end
def destroy
#house.destroy
redirect_to root_path
end
private
def set_house
#house = House.friendly.find(params[:id])
authorize #house
end
def house_params
params.require(:house).permit(:sku, :name, :price_cents, :width, :length, :wall, pictures: [])
end
end
Below is the normal index where I split houses up in categories starting with category_id: 2 (normal garden houses), then 1 (gazebos) and finally 3 (garages). This is partial which is rendered app/views/houses/index.html.erb
<% if !#category %>
<%= render 'first-banner-home' %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.where(category_id: 2).each do |house| %>
<div class="col-sm-6 col-md-4">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<div class="container catalog">
<h3><%= t('home.gazebos') %></h3>
<div class="row">
<% #houses.where(category_id: 1).each do |house| %>
<div class="col-sm-6">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top-alt", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<div class="container catalog">
<h3><%= t('home.garages') %></h3>
<div class="row">
<% #houses.where(category_id: 3).each do |house| %>
<div class="col-sm-6">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top-alt", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% elsif params[:h].present? %>
<%= render "results_index" %>
<% else %>
<%= render "category_index" %>
<% end %>
This is the index where the houses are filtered based on their wall thickness (see in app/controllers/houses_controller.rb ). This is where I want the house to order based on their category_id, which doesn’t work at the moment.
<% content_for(:title) do %><%= t('topbar.brand') %><% end %>
<% content_for(:og_site_name) do %><%= t('topbar.brand') %><% end %>
<% content_for(:description) do %><%= t('garden_houses.meta_description') %><% end %>
<% content_for(:og_image) do %><%= cl_image_path("https://res.cloudinary.com/www-ibizagardenhouses-com/image/upload/c_scale,h_630,w_1200/v1558696079/ibi-3/image.jpg") %><% end %>
<% content_for(:og_description) do %><%= t('garden_houses.meta_description') %><% end %>
<%= render 'first-banner-results' %>
<% if #houses.count >= 4 %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.each do |house| %>
<div class="col-sm-6 col-md-4">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% else %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.each do |house| %>
<div class="col-sm-6">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top-alt", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% end %>
This is exactly the same html as app/views/houses/results_index.html.erb , but where I show all the houses (params[h: 1]) in a layout that’s not the same as the home page. Same problem here as on the filtered results page.
<% content_for(:title) do %><%= t('topbar.brand') %><% end %>
<% content_for(:og_site_name) do %><%= t('topbar.brand') %><% end %>
<% content_for(:description) do %><%= t('garden_houses.meta_description') %><% end %>
<% content_for(:og_image) do %><%= cl_image_path("https://res.cloudinary.com/www-ibizagardenhouses-com/image/upload/c_scale,h_630,w_1200/v1558696079/ibi-3/image.jpg") %><% end %>
<% content_for(:og_description) do %><%= t('garden_houses.meta_description') %><% end %>
<%= render 'first-banner-all' %>
<% if #houses.count >= 4 %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.each do |house| %>
<div class="col-sm-6 col-md-4">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% else %>
<div class="container catalog">
<%= render "filter_buttons" %>
<div class="row">
<% #houses.each do |house| %>
<div class="col-sm-6">
<div class="card">
<% if house.pictures? %>
<div class="imageTop" style="position: relative;">
<%= cl_image_tag(house.pictures[0], :quality=>50, :width=>1800, :crop=>"scale", class: "card-img-top-alt", alt: house.name + " " + house.category.name) %>
<%= link_to "", house_path(house), class: "card-link" %>
</div>
<% end %>
<div class="card-body indexBody">
<div class="card-price">
<h3 class="card-title"><%= house.name %></h3>
<h3><%= house.length.to_f / 100 %> x <%= house.width.to_f.to_f / 100 %> m</h3>
</div>
<div class="card-price">
<% if house.price_present == false %>
<h3><%= t('show.consult') %></h3>
<% else %>
<h3><%= humanized_money_with_symbol(house.original_price) %><span style="color: red"> - 15%</span> = <%= humanized_money_with_symbol(house.price) %></h3>
<% end %>
</div>
<% if policy(house).update? %>
<%= link_to "Edit", edit_house_path(house) %>
<% end %>
<% if policy(house).destroy? %>
<%= link_to "Remove", house_path(house), method: :delete, data: { confirm: "Are you sure?" } %>
<% end %>
</div>
</div>
</div>
<% end %>
</div>
</div>
<%= render "last-banner" %>
<% end %>
As you can see, there's a lot of duplication of code (not very DRY) and so I'd like a little help in getting more DRY and have the houses be ordered by category_id and then by price.
I'd appreciate your help.
It's not clear to me what you tried so far, but if all you need is to sort by category_id, I think you can define a scope within your house model as follow:
scope :sort_by_category_id_asc, ->{
order(arel_table[:category_id].asc)
}
Then you can use that scope as follow: House.where(...).sort_by_category_id_asc, also you can use desc, depends on how you want to order the result.
Hope this helps! 👍
I created a method that can sort houses by its category_id. If you want to sort it by other things just change category_id to your desired thing. You can sort it ascending or descending order. Here it is:
def sort_by_category_id(houses, order)
case order_by
when "asc"
houses = houses.sort_by{ |house|
house[:category_id]
}
when "desc"
house= house.sort_by{ |house|
house[:category_id]
}.reverse!
end
house
end
Don't forget to call this method wherever you want it to be worked. Below code will sort your houses by category_id and save it in sorted_houses variable. I
sorted_houses_asc = sort_by_category_id(#houses, "asc")
sorted_houses_desc = sort_by_category_id(#houses, "desc")
Hope this helped you somehow.
I would like to display an agenda that shows who is available for roster for the next seven days, with the following logic:
Looping through each of the 7 days, for each day:
If the leave starts today, show Starts %H:%M
If the leave finishes today, show Finishes %H:%M
If the leave starts and finishes today, show %H:%M - %H:%M
If the leave doesn't start or finish today but spans over today, show all day
Should include leave that start or finish outside of the 7 days but span the 7 days being displayed.
I am hoping for someone to point me in the right direction preferably using Rails and Postgres. I am not against doing the queries for each day since at most there will only be 30 days displayed, but also looking for reasonably performant code since there could be 100+ leave records per day.
First example that does not fulfill the criteria outlined above.
<% #dates.each do |d| %>
<h5><%= d.strftime("%A %d %b") %></h5>
<% #leave = Leave.where('(start_at BETWEEN ? AND ?) OR (end_at BETWEEN ? AND ?)', d.beginning_of_day, d.end_of_day, d.beginning_of_day, d.end_of_day) %>
<% #leave = #leave.where.not('end_at < ?', Time.current) %>
<% if #leave.any? %>
<ul>
<% #leave.each do |leave| %>
<% if leave.single_day? && leave.start_at.to_date == d %>
<li>
<label class="label label-danger"><%= leave.start_at.strftime('%H:%M') %> - <%= leave.end_at.strftime('%H:%M') %></label>
<%= leave.user.name %>
</li>
<% elsif !leave.single_day? %>
<% if leave.start_at.to_date == d %>
<li>
<label class="label label-danger">From <%= leave.start_at.strftime('%H:%M') %></label>
<%= leave.user.name %>
</li>
<% elsif leave.end_at.to_date == d %>
<li>
<label class="label label-danger">Until <%= leave.end_at.strftime('%H:%M') %></label>
<%= leave.user.name %>
</li>
<% else %>
<li>
<label class="label label-danger">All Day</label>
<%= leave.user.name %>
</li>
<% end %>
<% end %>
<% end %>
</ul>
<br/>
<span class="label label-success" style="margin-right: 10px;">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= current_account.users.active.where.not(id: #leave.map(&:user_id)).count %> Available
<% else %>
<span class="label label-success" style="margin-right: 10px;">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= current_account.users.active.count %> Available
<% end %>
<br />
<br />
<% end %>
I would start with something like this:
In the model:
def starts_on?(date)
start_at.to_date == date
end
def ends_on?(date)
end_at.to_date = date
end
def covers?(date)
leave.start_at.to_date <= date && leave.end_at.to_date >= date
end
def starts_and_ends_on?(date)
starts_on?(date) && ends_on?(date)
end
In the controller:
#dates = # define the date range like you already do, I assume it is an array
#leaves = Leave.includes(:user).
where('start_at =< ? AND end_at >= ?', dates.max, dates.min)
In the helper:
def relevant_leaves_for_date(date, leaves)
leaves.select { |leave| leave.covers?(date) }
end
def leave_description_for_date(leave, date)
if leave.starts_and_ends_on?(date)
"#{leave.start_at.strftime('%H:%M')} - #{leave.end_at.strftime('%H:%M')}"
elsif leave.starts_on?(date)
"From #{leave.start_at.strftime('%H:%M')}"
elsif leave.ends_on?(date)
"Until #{leave.end_at.strftime('%H:%M')}"
else
'All day'
end
end
def available_users(leaves)
current_account.users.active.count - leaves.size
end
In the view:
<% #dates.each do |date| %>
<h5><%= date.strftime("%A %d %b") %></h5>
<% leaves = relevant_leaves_for_date(date, #leaves) %>
<% if leaves.any? %>
<ul>
<% leaves.each do |leave| %>
<li>
<label class="label label-danger">
<%= leave_description_for_date(leave, date) %>
</label>
<%= leave.user.name %>
</li>
<% end %>
</ul>
<% end %>
<span class="label label-success">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= available_users(leaves) %> Available
<% end %>
You might notice that I remove the <br> and style tags from the html. Please do not use <br> for styling or style attributes in the html. Add class the the tags and style them in your css file.
The reason why case 4 & 5 are not working is you are not fetching the leaves which started before the beginning of day or which are going to end after the end of day. So you can fetch all leaves which have not ended yet.
<% #leave = Leave.where('(end_at >= ?', d.beginning_of_day) %>
And then in application_helper.rb, you can have a function like this,
def check_for_leave(leave,d)
msg = ""
if leave.single_day? && leave.start_at.to_date == d
msg = "#{leave.start_at.strftime('%H:%M')} - #{leave.end_at.strftime('%H:%M')}"
elsif !leave.single_day?
if leave.start_at.to_date == d
msg = "From #{leave.start_at.strftime('%H:%M')}"
elsif leave.end_at.to_date == d
msg = "Until #{leave.end_at.strftime('%H:%M')}"
else
msg = "All Day"
end
return msg
end
In html.erb file
<% #dates.each do |d| %>
<h5><%= d.strftime("%A %d %b") %></h5>
<% #leave = Leave.where('(end_at >= ?', d.beginning_of_day) %>
<% if #leave.any? %>
<ul>
<% #leave.each do |leave| %>
<li>
<label class="label label-danger">
<%= check_for_leave(leave, d) %>
</label>
<%= leave.user.name %>
</li>
<% end %>
</ul>
<br/>
<span class="label label-success" style="margin-right: 10px;">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= current_account.users.active.where.not(id: #leave.map(&:user_id)).count %> Available
<% else %>
<span class="label label-success" style="margin-right: 10px;">
<span class="glyphicon glyphicon-ok"></span>
</span>
<%= current_account.users.active.count %> Available
<% end %>
<br />
<br />
<% end %>
For example I have this file:
_goal.html.erb
<table>
<tr>
<%= goal.name %>
<span class="label label-info"><%= goal.deadline.strftime("%d %b %Y") %></span>
</tr>
</table>
It is being rendered from the home page:
<h1><b>Goals</b></h1>
<%= render #unaccomplished_goals %>
<%= render #accomplished_goals %>
<% end %>
How can we wrap an accomplished goal with <span class="label label-info-success"> but if it is an unaccomplished goal keep it <span class="label label-info">?
In the controller:
#accomplished_goals = current_user.goals.accomplished
#unaccomplished_goals = current_user.goals.unaccomplished
Here was my latest attempt, which just made them all -info:
<% if #unaccomplished_goals == true %>
<span class="label label-info"><%= goal.deadline.strftime("%d %b %Y") %></span>
<% else #accomplished_goals == true %>
<span class="label label-warning"><%= goal.deadline.strftime("%d %b %Y") %></span>
<% end %>
Maybe you'll have more luck :)
Thank you so much.
Create a helper method that returns the correct classes for the goal's status. In application_helper.rb:
def deadline_label_class(goal)
if goal.accomplished?
'label label-info'
else
'label label-warning'
end
end
This assumes that Goal has an instance method called accomplished? which returns true/false. You may have to write that method if it doesn't exist or use some other criteria.
Then use the helper in the _goal.html.erb template:
<table>
<tr>
<%= goal.name %>
<span class="<%= deadline_label_class(goal) %>">
<%= goal.deadline.strftime("%d %b %Y") %>
</span>
</tr>
</table>
I have the following code:
<span class="bookings">
<span class="col-md-2">
<h4><%= time_tag(Date.today + 1.days) %></h4>
<% #booking.each do |b| %>
<% if b.date == Date.today + 1.days && b.type == "Hot Desk" %>
<% if b.desk == #hotdesk.code %>
<span class="glyphicon glyphicon-remove booked-show"></span>
<% end %>
<% end %>
<% end %>
</span>
</span>
<span class="bookings">
<span class="col-md-2">
<h4><%= time_tag(Date.today + 2.days) %></h4>
<% #booking.each do |b| %>
<% if b.date == Date.today + 2.days && b.type == "Hot Desk" %>
<% if b.desk == #hotdesk.code %>
<span class="glyphicon glyphicon-remove booked-show"></span>
<% end %>
<% end %>
<% end %>
</span>
</span>
Which extends on to however many days I want to display availability of bookings for. What I would like to achieve is writing only one of these blocks of codes out and having it loop through where it says Date.today + 1.days and increase the value of the days by 1 each loop up to 20 or so times.
Any ideas on a way to do this to save me writing this code over and over again?
<span class="bookings">
<% 1.upto(YOUR_COUNT.to_i).each do |day_count| %>
<span class="col-md-2">
<h4><%= time_tag(Date.today + day_count.days) %></h4>
<% #booking.each do |b| %>
<% if b.date == Date.today + day_count.days && b.type == "Hot Desk" %>
<% if b.desk == #hotdesk.code %>
<span class="glyphicon glyphicon-remove booked-show"></span>
<% end %>
<% end %>
<% end %>
</span>
<% end %>
</span>