So i have this in my view
<% #events.each do |event| %>
<% if event.eventcomplete %>
<% else %>
<tr>
<td colspan="7">
<p>
No Events could be found.
</p>
</td>
</tr>
<% end %>
This is on my search results page,
However what im wanting if there is no eventcomplete, Just display one No events found,
At the moment i'm gettting around 100 events found but, None of them are complete. So i'm getting around 100 "No Events could be found"
Thanks for any help
Sam
I don't know what your code looks like, but something smells wrong to me that you're filtering by eventcomplete in your view both for determining which rows to display and for whether or not to show your "No results" message. Presumably you will later want to do other things using this collection (like pagination), so I'd suggest filtering the collection in the controller:
# controller code
#in_progress_events = #events.where(eventcomplete: false)
Once the collection is being properly filtered before it hits the view, check out the points in this answer for tips on display: Rails: An elegant way to display a message when there are no elements in database
Your code is missing an <% end %> tag.
<% #events.each do |event| %>
<% if event.eventcomplete %>
[insert view code to show if event.eventcomplete is true]
<% else %>
<tr>
<td colspan="7">
<p>
No Events could be found.
</p>
</td>
</tr>
<% end %>
<% end %>
Actually the code is doing exactly what it should do,
your html Block was defined in your each block, this is why it got raised 100 times.
I just fixed it with Helper Variables, but it is just a workaround
You should make use of more static methods in your models, just define it
Please make sure your business logic holds place in your models:
Fat models, Thin Controllers/Views
this should work
<% #there_is_no_eventcomplete = false %>
<% #events.each do |event| %>
<% if event.eventcomplete %>
#there_is_no_eventcomplete = true
<% end %>
<% end %>
<% if #there_is_no_eventcomplete == false %>
<tr>
<td colspan="7">
<p>
No Events could be found.
</p>
</td>
</tr>
<% end %>
You want to use a scope on your model which you can then call in the controller. I'm not sure how you've set up your model or how you determine if an event is completed, so lets assume you have a boolean attribute completed on your model:
event.rb
class Event
def self.completed
where(complete: false)
end
end
controller
#events = Event.completed
view
<% unless #events.nil?
<% #events.each do |event|%>
// your code
<% end %>
<% else %>
// your code
<% end %>
Related
i want to achieve a nested loop without duplicates in a have and belongs to many relationship
i have a model 'campaign' and for each campaign i also have campaign data.
i want to display each campaign with its campaign data in a table. (nested)
#campaigns = current_user.campaigns
<% #campaigns.each do |item| %>
<% i = item.campaign_data %>
<% i.each do |cdata| %>
<%= cdata.date %>
<tr>
<td>
<%= item.name %>
</td>
<td>
<%= cdata.date %>
</td>
<td>
</td>
</tr>
<% end %>
<% end %>
my problem is that my campaigns get duplicated.
I want to achieve something like this:
Each campaign is listed in the table with its corresponding campaign_data directly below it, and if no campaign_data is left the next loop begins with the next campaign - is this possible?
best regard
You might be getting duplicated campaigns as you are using <%= item.name %> inside the <% i.each do |cdata| %> loop. So, if one campaign has 4 campaign_datas you will see the campaign name 4 times.
You should use naming conventions properly, if the campaign has many data campaign_data then you should specify so in association i.e. has_many :campaign_datas
Also, the Following code should be in the controller
#campaigns = current_user.campaigns.include(:campaign_datas)
Note:- I used include to avoid n + 1, please read here.
In view
<% for campaign in #campaigns %>
<% next if #campaigns.campaign_datas.blank? %>
<tr>
<td><%= item.name %></td>
</tr>
<% for campaign_data in #campaigns.campaign_datas %>
<tr>
<td><%= campaign_data.date %></td>
</tr>
<% end %>
<% end %>
Note:-
<% next if #campaigns.campaign_datas.blank? %> line is used to skip the campaign if it has no campaign data.
TheChamp helped me out to sort out with the array of hashes issue. Thanks. Now I would like to improve on that. It is really messy in the views
Move the code to model, so only calling the instance variable will show the desired result. Like one variable for flight types, the departure times, price structure, etc.
Have the result sorted in the model itself, based on some conditions. Like for price, default to lowest first.
It takes a lot of time to get the API response. What are the various options to cache the response, so results are instantaneous. Also, what values need to be checked to ensure the cache is fresh.
This is my code base. (for ur consideration, a portion of API response - http://jsfiddle.net/PP9N5/)
Model
class Cleartrip
include HTTParty
debug_output $stdout
base_uri "api.staging.cleartrip.com/air/1.0/search"
headers 'X-CT-API-KEY' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
format :xml
def self.get_flight
response = get("?from=DEL&to=BLR&depart-date=2014-08-10&adults=1&children=0&infants=0")
if response.success?
response
else
raise response.message
end
end
Controller
# This does nothing
expires_in 20.minutes, public: true
#flight = Cleartrip.get_flight
Views
<table>
<tbody>
<% #flight["air_search_result"]["onward_solutions"]["solution"].each do |h| %>
<tr>
<td> # This gets the flight info
<% Array.wrap(h["flights"]["flight"]["segments"]["segment"]).each do |segment| %>
<strong><%= segment['airline'] %></strong> <br>
<%= segment['departure_airport'] %> - <%= segment['departure_date_time'] %> ||
<%= segment['arrival_airport'] %> - <%= segment['arrival_date_time'] %> <br>
<% end %>
<hr>
</td>
<td> # this gets the type of fare, Refundable/ Non-refundable
<%= h["pax_pricing_info_list"]["pax_pricing_info"]["pricing_info_list"]["pricing_info"]["fare_type"] %>
</td>
<td> # This gets the fare structure
<% h["pax_pricing_info_list"]["pax_pricing_info"]["pricing_info_list"]["pricing_info"]["pricing_elements"]["pricing_element"].each do |f| %>
<%= f['category']%> - <%= f['amount'] %> <br>
<% end %>
</td>
<td> # The pricing summary
<strong><%=h["pricing_summary"]["total_fare"] %></strong>
</td>
</tr>
<% end %>
</tbody>
</table>
Appreciate general guidelines.
Thanks.
I am making some printable tables for a client with a Ruby on Rails 3.1 app and need to repeat table headers on each page. Unfortunately, at the moment, WebKit browsers do not support a CSS-based solution.
To solve this issue, I thought I would use the will_paginate gem.
Controller
def
#books = current_library.books.order('books.title ASC')
end
Current View Code
<% #books.each do |b| %>
<table>
<thead><th><%= b.title %></th></thead>
<tbody>
<% b.chapters.each do |chap| %
<td><%= chap.number %> ... <%= chap.name %></td>
<% end %>
</tbody>
</table>
<% end %>
How do I setup the pages and step through each one? In other words, how do I get all the pages of the pagination on one view page?
Alternatively, is there a better approach I should pursue?
You might be better off using Enumerable#each_slice here. It allows you to split a large enumerable object into a series of smaller slices, and then iterate on those slices. It's quite nice for this sort of thing, doesn't require any extra math in your loops, and doesn't require a gem.
Here's an example for a collection with 10 items on a page:
<% #books.each_slice(10) do |slice| %>
<h1>Header Information</h1>
<h2>Awesome</h2>
<% slice.each do |book| %>
<table>
<thead><tr><th><%= book.title %></th></tr></thead>
<tbody>
<% book.chapters.each do |chap| %
<tr><td><%= chap.number %> ... <%= chap.name %></td></tr>
<% end %>
</tbody>
</table>
<% end %>
<p>Some footer information</p>
<% end %>
This approach will only work if you assume that each book record takes about the same amount of space (so you don't end up with oversized or undersized pages), but that would be a problem with will_paginate as well.
How to use arrays and get order date?
I get the date when the order was shipped.( order.line_items_line_item.fulfillment.created_at)
Help plz thx
I'm doing this
controller
#order = ShopifyAPI::Order.find(:all)
views -work
<% #order.each do |order| %>
<span class="highlight"><%= order.customer.email %></span>
<%= order.line_items.each do |line_item| %>
<span class="note"><% line_item.title %></span>
<% end %>
<% end %>
</ul>
<% end %>
views -don't work
<% #order.each do |order| %>
<%= order.line_items.each do |line_item| %>
<span class="note"><% line_item.created_at %></span>
<% end %>
<% end %>
</ul>
<% end %>
views -don't work
<% if #order.line_items %>
<% #order.line_items.each do |line_item| %>
<tr>
<td><%= line_item.created_at %></td>
</tr>
<% end %>
<% end %>
I’m not sure I understand your question, but if you’re looking for when an order was created, you want
#order.created_at
Take a look at the JSON responses in http://api.shopify.com/order.html or do a
puts #order.inspect
to see what kind of data comes back from an Order API call.
Line items don't have a created_at field, they're properties of the order in the same way that adress lines are part of an address.
There's a separate object that deals with order fulfillments. Here's the page on the docs: http://api.shopify.com/fulfillment.html
Using the ruby gem you can just call order.fulfillments to get an array of fulfillments. Then you can loop over those to see when the line items were fulfilled.
I have the following requirement.
Ex: There is a transaction table where it has columns say, transaction_name and amount. I want to loop through the transactions and display their details (transaction_name and amount) and finally I want to display the total amount (sum of all the amounts) in the head (before the loop) section of my page. (Think about it as a summary display)
Example page structure would be like
Sum of all the transactions - 200
transaction amount
trn1 100
trn2 50
trn3 50
And I tried to use yield and content_for tag but no luck.
my code is as follows (i'm calling inside my erb file.)
<%= yield :transaction_summary %>
<table>
<% total_amount = 0%>
<%for transaction in #transactions%>
<tr>
<td><%= transaction.transaction_name %></td>
<td><%= transaction.amount %></td>
<% total_amount += transaction.amount %>
</tr>
<%end%>
</table>
<% content_for :transaction_summary do %>
<h1>
Sum of all the transactions - <%= total_amount %>
</h1>
<% end %>
And
I'm using with inside a view (not inside a layout)
I'm using rails 2.2.2
Please help me and let me know if there is a better way
thanks in advance
cheers
sameera
EDIT:
Actually what I want to do is , Display some details before a particular loop where those details can be collected after the loop
Ex: If i have an array of transaction objects, I want to show a count of pass and failed transactions before the transactions loop in my view
thanks
In other cases where you really need to reuse content_for, the following may be useful.
In Rails 4, you can pass :flush => true as an option to content_for:
<% content_for :example, flush: true do %>
<h1>Deletes previous content</h1>
<% end %>
In Rails 3.1.1 (approx) you can delete the content from the view_flow when you yield by defining and using the following (eg in application_helper):
def yield_and_flush!(content_key)
view_flow.content.delete(content_key)
end
I think you have the wrong idea about content_for and yield. :) http://guides.rubyonrails.org/layouts_and_rendering.html
<h1>
<%= #transactions.collect(&:amount).sum -%>
</h1>
<table>
<%for transaction in #transactions%>
<tr>
<td><%= transaction.transaction_name %></td>
<td><%= transaction.amount %></td>
</tr>
<%end%>
</table>
edit -
Regarding collecting data, I suggest you put them in helper methods:
#transactions_helper.rb
def transactions_total transactions
#transactions_total ||= #transactions.collect(&:amount).sum
end
def passed_transactions transactions
#passed_transactions ||= #transactions.collect{|transaction| transaction.passed == true}
end
def failed_transactions transactions
#failed_transactions ||= transactions - passed_transactions(transactions)
end
Just noticed your comment to theTRON. The whole dry principle doesn't really apply to executing tiny logic such as looping through a array.
I would write a helper method which calculates the total separately, perhaps something along the lines of:
# app/helpers/transactions_helper.rb
def calculate_total(transactions)
total = 0
transactions.each {|transaction| total += transaction.amount}
total
end
Then you can display it in your view wherever you like, with:
<%= calculate_total(#transactions) %>
In Rails 3 you can yield after content_for; so your code will become:
<% content_for :transaction_table do %>
<table>
<% total_amount = 0%>
<% for transaction in #transactions do %>
<tr>
<td><%= transaction.transaction_name %></td>
<td><%= transaction.amount %></td>
<% total_amount += transaction.amount %>
</tr>
<%end%>
</table>
<% content_for :transaction_summary do %>
<h1>
Sum of all the transactions - <%= total_amount %>
</h1>
<% end %>
<% end %> <!- End content_for :transaction_table -->
<%= yield :transaction_summary %>
<%= yield :transaction_table %>
Note:
<% content_for :transaction_summary do %>
doesn't have to be inside of
<% content_for :transaction_table do %>
, but for some more complex cases it could.