I was looking for a way to improve this piece of code:
<% if A || B %>
<a></a>
<ul>
<% if A %>
<li>Action A</li>
<% end %>
<li>Action C</li>
<% if B %>
<li>Action B</li>
<% end %>
</ul>
<% end %>
this involves to evaluate A, eventually B and then A again and B again. Any idea on how to improve that code?
P.S.
Order of actions matters.
In your controller:
#action_list = []
if A || B
#action_list << "Action A" if A
#action_list << "Action C"
#action_list << "Action B" if B
end
In your view:
<% if #action_list.count > 0 %>
<a></a>
<ul>
<% #action_list.each do |action| %>
<li><%= action %></li>
<% end %>
</ul>
<% end %>
I'd go with the same approach as msergeant, but stick it in a class like so:
class ActionListItems
def initialize(a = nil, b = nil)
#a = a
#b = b
end
def render?
!!(#a || #b)
end
def each
yield "Action A" if #a
yield "Action C"
yield "Action B" if #b
end
end
action_list_items = ActionListItems.new "a", "b"
puts action_list_items.render?
#=> true
action_list_items.each do |item|
puts item
end
#=> Action A
#=> Action C
#=> Action B
Related
I am using Ruby on Rails 5.2.3 and Mongoid 7.0
I need to be able to sort multiple models (Item and Text) in one cotroller.
Now only Item or Text is sorted, it is necessary that Position was set in relation to each other.
class UsersController < ApplicationController
def sort
params[:item].each_with_index do |id, index|
Item.where(id: id).update_all(position: index + 1)
end
head :ok
end
def admin
#user_items = #user.user_feed
end
end
admin.html.erb
<div id="items" data-url="<%= sort_users_path %>">
<%= render partial: 'users/user_item', collection: #user_items %>
</div>
_user_item.html.erb
<% if user_item[:title].present? %>
<div id="item_<%= user_item[:id] %>">
<%= user_item[:position] %>
</div>
<% end %>
<% if user_item[:text].present? %>
<div id="item_<%= user_item[:id] %>">
<%= raw user_item[:position] %>
</div>
<% end %>
User.rb
def user_activity
activity_items = []
items.each do |item|
activity_item = {}
activity_item[:id] = item.id
activity_item[:url] = item
activity_item[:title] = item.title
activity_item[:position] = item.position
activity_item[:item_link] = item.url
activity_items << activity_item
end
texts.each do |text|
activity_item = {}
activity_item[:id] = text.id
activity_item[:url] = text
activity_item[:text] = text.text
activity_item[:position] = text.position
activity_items << activity_item
end
activity_items.sort_by! { |activity_item| activity_item[:position] }
activity_items
end
def user_feed
activity_items = user_activity
activity_items.sort_by! { |activity_item| activity_item[:position] }
activity_items
end
Just needed to add Text.where(id: id).update_all(position: index + 1)
def sort
params[:item].each_with_index do |id, index|
Item.where(id: id).update_all(position: index + 1)
Text.where(id: id).update_all(position: index + 1)
end
head :ok
end
I'd like to create a todo list looking for any cell that matches today's date on either agreement, start or due date.
<% #project.where("project_date_agreement + project_date_start + project_date_due > ?", Date.today).each do |tasks_today| %>
<ul>
<li>Item Due Today</li>
</ul>
<% end %>
Any help getting me in right direction would be appreciated.
You want to use OR conditions in your where clause. Properly speaking this would be in your controller.
#projects = Project.where('date_agreement = ? OR date_start = ? or date_due = ?', Date.today, Date.today, Date.today)
In your Project Model you might want to create a field that say's what's due...
def due_because
due_array = []
due_array << 'Agreement date' if date_agreemnt == Date.today
due_array << 'Start date' if date_start == Date.today
due_array << 'Due date' if date_due == Date.today'
due_array.join(', ')
end
Then in your view you would iterate over the #projects
<ul>
<li>Items Due Today</li>
<% #projects.each do |project| %>
<li><%=project.name%> <%=project.due_because%></li>
<% end %>
</ul>
if you asking one row and different column, how about if you combine with table
<% #tasks = #projects.where("date_agreement = ? AND date_start = ? AND date_due = ?",Date.today ,Date.today, Date.today) %>
<table>
<tr>
<ul>
<% #tasks.each do |task| %>
<td>
<li><%= task.check_box :item_due %></li>
</td>
<% end %>
</ul>
</tr>
</table>
I have a set of repeating records that should contain a string that should contain a block of conditional text:
<% if #order.payments.present? %>
<% #order.payments.each do |p| %>
<tr>
<td>Payment</td>
<td>There was a "MY CONDITIONAL TEXT" for <span><%= number_to_currency(p.try(:amount)) %></span></td>
</tr>
<% end %>
<% end %>
So "MY CONDITIONAL TEXT" options would be:
"Partial Payment" when p.amount < #order.value
"Excessive Payment" when p.amount > #order.value
"Payment" when p.amount = #order.value
Is there any way to create a helper method in the OrdersHelper "payment_type" that will help me avoid conditional statements in my views?
yes create a method in helper for that
def method_name(order_value, payment_amount)
if payment_amount < order_value
"Partial Payment"
elsif payment_amount > order_value
"Excessive Payment"
elsif payment_amount = order_value
"Payment"
end
end
now in view
<%= method_name(#order.value, p.amount)%>
I'm using rails 4. And i'm trying to output menu navigation. I got tble PlaceType with category and title columns. There are 6 categories and i want to output Category only 1 time and then output all titles, that brlong to this ategory. How can i achieve that?
<% #types = PlaceType.all %>
<% #types.each do |type| %>
<ul><%= type.category %>
<li><%= type.title %></li>
</ul>
<% end %>
That's my way of sloving this problem:
<% #types = PlaceType.all %>
<% #types.group_by(&:category).each do |category, type| %>
<ul><%= category %>
<% type.each do |t|%>
<li><%= t.title %></li>
<% end %>
</ul>
<% end %>
Use the group_by method available in Array.
#types.group_by {|type| type.category}
Will give you a hash that looks something like this:
{
"Category A" => ["Title 1", "Title 2"],
"Category B" => ["Title 3"],
"Category C" => ["Title 4", "Title 5"]
}
Now you can loop through the resulting hash instead, to display titles under each category.
I am attempting to perform a series of requests that will organize the results in a given date span in a way where each location will live on the top level, and contain an another array with each set of results. Here is what I have so far:
locations = Location.all
#requests = []
locations.each do |location|
request = PurchaseRequest.where('created_at >= ? AND created_at <= ? AND location_id = ?', params[:start_date], params[:end_date], location.id).order(:location_id)
#requests.push(location => request)
end
My ideal (non-working) implementation in the view would look something like:
<ul>
<% #requests.each do |location| %>
<li>location[0].name</li>
<ul>
<% location[1].each do |request| %>
<li>request.name</li>
<% end %>
</ul>
<% end %>
</ul>
Try something like this:
#requests = {}
Location.all.each do |location|
#requests[location.name] = PurchaseRequest.where('created_at >= ? AND created_at <= ? AND location_id = ?', params[:start_date], params[:end_date], location.id).order(:location_id)
end
and:
<ul>
<% #requests.each do |location_name, request_list| %>
<li><%= location_name %></li>
<ul>
<% request_list.each do |request| %>
<li><%= request.name %></li>
<% end %>
</ul>
<% end %>
</ul>
#requests becomes a hash with the key being the location name and the value being the purchase requests.