Rails partial show latest 5 kases - ruby-on-rails

I have my application setup with a few different partials working well. I have asked here how to get a partial working to show the latest entry in the kase model, but now I need to show the latest 5 entries in the kase model in a partial.
I have duplicated the show most recent one partial and it's working where I need it to but only shows the last entry, what do I need to change to show the last 5?
_recent_kases.html.erb
<% if Kase.most_recentfive %>
<h4>The most recent case reference is <strong><%= Kase.most_recentfive.jobno %></strong></h4>
<% end %>
kase.rb
def self.most_recentfive
first(:order => 'id DESC')
end
Thanks,
Danny
EDIT
def self.most_recentfive
all(:order => 'id DESC', :limit=>5)
end
If I add the above code I get the following Error Message:
NoMethodError in Dashboard#index
Showing app/views/kases/_recent_kases.html.erb where line #2 raised:
undefined method `jobno' for #<Array:0x105984c60>
Extracted source (around line #2):
1: <% if Kase.most_recentfive %>
2: <h4>The most recent case reference is <strong><%= Kase.most_recentfive.jobno %></strong></h4>
3: <% end %>

def self.most_recentfive
all(:order => 'id DESC', :limit=>5)
end
EDITED TO ADD:
Then, in your partial, to display the results, you do
<% if Kase.most_recentfive %>
<h4>The most recent five case references are
<% Kase.most_recentfive.each do |k|%>
<strong><%= link_to k.jobno, k %></strong><br />
<% end %>
</h4>
<% end %>

Related

NameError in ruby on rails

So I am making an app to manage projects and its task,
using a tutorial I have made some basic stuff.
Now I want to add a timeline to my page, so I wrote this in my pr_list.rb (model file)
def timeline
#pr_lists.each do |pr_list|
pr_list.pr_items.each do |pr_item|
if pr_item.completed?
#timeline = "#{pr_item.descrpition}: {#{pr_item.completed_at}}"
end
end
end
end
And i called it in my pr_list/views/index page.
<h1><%= pr_list.timeline %></h1>
but I get
NameError (undefined local variable or method `pr_list' for #<ActionView::Base:0x00000000029fb8>
Did you mean? #pr_lists")
At this point even if I just code it like to output a string, it just does not work.
if I try any other things, it gives me a NoMethodError
while the rest of the methods work.
and the above code also works if I write it in HTML.ERB index file as an embedded ruby.
I am new to Ruby on Rails.
pr_list is local to the block defined in the controller so it is not accessible from the template.
You could iterate on #pr_lists from within the view file (see this question for reference):
<% #pr_lists.each do |pr_list| %>
<% pr_list.pr_item.each do |pr_item| %>
<% if pr_item.completed? %>
<h2><%= pr_item.description %>: <%= pr_item.completed_at %></h2>
<% end %>
<% end %>
<% end %>

Do not understand locals in rails - getting a No method error

I am fairly new to rails and I am trying to the shopping cart html view to the site admin when a order is made. The email portion is working just fine with simple html but when I add the ruby code to render the views page I get the following error:
NoMethodError in Charges#create
Showing /home/ubuntu/workspace/app/views/order_mailer/order_email.html.erb where line #7 raised:
undefined method `size' for nil:NilClass
Extracted source (around line #7):
5
6
7
<%= render "carts/shopping_cart", size: #order_items.size %>
Rails.root: /home/ubuntu/workspace
Application Trace | Framework Trace | Full Trace
app/views/order_mailer/order_email.html.erb:7:in `_app_views_order_mailer_order_email_html_erb___1590505826361550286_70123907983000'
app/mailers/order_mailer.rb:11:in `order_email'
app/controllers/charges_controller.rb:10:in `create'
From what I have read I think I need to add locals to my render code but I am confused on what exactly locals are and what they would be in my code. If I am completely off track and this error has nothing to do with locals I would appreciate some guidance in the right direction.
Thanks!
order_email view:
<h1>You have a new order </h1>
<%= render "carts/shopping_cart", size: #order_items.size %>
The view I am trying to render in the email:
<% if !#order_item.nil? && #order_item.errors.any? %>
<div class="alert alert-danger">
<ul>
<% #order_item.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<% if #order_items.size == 0 %>
<p class="text-center">
There are no items in your shopping cart. Please <%= link_to "go back", root_path %> and add some items to your cart.
</p>
<% else %>
<% #order_items.each do |order_item| %>
<%= render 'carts/cart_row', product: order_item.product, order_item: order_item, show_total: true %>
<% end %>
order_mailer.rb:
class OrderMailer < ApplicationMailer
default from: "xxxx#gmail.com"
def order_email(order_items)
#order_items = order_items
mail(to: "xxxx#gmail.com", subject: "Your subject")
end
end
I believe locals are only used when doing a render partial, which you should be able to do for this but you'd need to make a few adjustments.
Each of the partials' filename need to be adjusted to have and underscore in front of them, but you still reference them without the underscore (I know it's a bit confusing).
So rename carts/shopping_cart to carts/_shopping_cart
and then change where it's referenced to:
<%= render partial: "carts/shopping_cart", locals:{size: #order_items.size} %>
Do the same sort of thing with 'carts/cart_row'

ActiveRecord_Associations_CollectionProxy:0x0000000e490b98 in RoR

I'm creating a application using ruby on rails, but currently i'm suffering a problem like db relation, below my code:
Company
has_many :posts, :foreign_key => :company_id
Post
belongs_to :companies, :foreign_key => :company_id
controller
#post = current_user.companies.all
view
<% #post.each do |p| %>
<%= p.posts.post_title %>
<% end %>
Showing error above code.
If I debug like use <%= debug p.posts %> then showing all posts, which is under my companies but when I use <%= debug p.posts.post_title %> then showing ActiveRecord_Associations_CollectionProxy:0x0000000e490b98
Thanks
I think the problem here is that you are trying to call the method :post_title on p.posts, which is an ActiveRecord::Associations::CollectionProxy object.
In your example, p is a Company object, which has a method posts, which returns to you a CollectionProxy object that acts a lot like a list of posts. That list will not have a method post_title, but each element of that list will have a method post_title
So, instead of
<% #post.each do |p| %>
<%= p.posts.post_title %>
<% end %>
You will want something like:
<% #post.each do |company| %>
<% company.posts.each do |post| %>
<%= post.post_title %>
<% end %>
<% end %>
Two additional things to note:
1) The variable #post is inaccurately named. Inaccurate variable names will lead to confusion when trying to understand what is happening. current_user.companies.all returns a list of companies, and therefore, it should read:
#companies = current_user.companies.all
not
#post = current_user.companies.all
2) The actual error that is being shown to you likely says something like
Undefined Method 'post_title' for ActiveRecord_Associations_CollectionProxy:0x0000000e490b98
Not just
ActiveRecord_Associations_CollectionProxy:0x0000000e490b98
When debugging and asking for help, it's very important to note the entire message of the exception being raised.
Because companiy has_many :posts........ posts are objects you need a loop to show all posts e.g
p.posts.each do |post|

Rails .each except if

I have a rails table called Movies. Movies are being collected and saved from an API which means that some movies may have a release_date and some may not.
All Movies are being displayed on the home page and they are sorted by {|t| - t.release_date.strftime("%Y%m%d").to_i}
<% #movies.sort_by{|t| - t.release_date.strftime("%Y%m%d").to_i}.each do |movie| %>
<% movie.title %>
<% movie.release_date.strftime("%Y") %>
<% end %>
So this code works fine but only as long as the returned movies have a release date. If they don't have a release date assigned, it gives me the following error.
ActionView::Template::Error (undefined method `strftime' for nil:NilClass):
But im only getting this error if the movie has no release_date.
So how can i add an exception to only display films WITH a release_date, where using strftime would no longer be a problem.
I've tried
<% unless movie.release_date.blank? %>
<% #movies.sort_by{|t| - t.release_date.strftime("%Y%m%d").to_i}.each do |movie| %>
<% #movie.title %>
<% #movie.release_date.strftime("%Y") %>
<% end %>
<% end %>
But that doesn't work as it gives an undefined method for 'movie'
You should be able to use reject to reject nil release_date like follows:
<% #movies.reject{ |m| m.release_date.nil? } %>
Another problem is you are using the variable movie as instance variable #movie within your each block.
Try:
<% #movies.reject{ |m| m.release_date.nil? }.sort_by{|t| - t.release_date.strftime("%Y%m%d").to_i}.each do |movie| %>
<% movie.title %>
<% movie.release_date.strftime("%Y") %>
<% end %>
Update:
And yes, as pointed by #NicolasGarnil in his answer, it's better to do these in SQL side than in ruby side. Select only the required records and let database do the sorting. So you could update your code to be something like:
In controller:
#movies = Movie.where('release_date is not null').order('release_date desc');
Then in your view:
<% #movies.each do |movie| %>
<% movie.title %>
<% movie.release_date.strftime("%Y") %>
<% end %>
For performance reasons you should not be using ruby to sort your records. This should be done at a database level.
You should first ensure that the release_date values are persisted in an appropriate format and then just use Movie.order("release_date desc"). Records with null values will be placed at the end of the results.

Listing users in rails +template error

I am starting my learning process by first listing all the users.
First I had added an action in the controller as
def list_users
#users=User.find(:all)
end
And in the View users/list_users.html.erb I have added the line
list_users.html.erb:
<%= Time.now %>
<% #users.each do |user| %>
<%= user.firstname %>
<% end %>
And for routing I have added the routes as
map.list_users '/list_users', :controller => 'users', :action => 'list_users'
That's it .. when I run my app , it's showing me the error as
Development mode eh? Here is the error - #<ActionView::TemplateError:
ActionView::TemplateError (You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each) on line #7 of app/views/users/list_users.html.erb:
Why so?
Solution:
I myself find that the controller action is under protected, that's why it showed me the error.
It seems that you didn't use the login method in list_users.html.erb, where did you used it?
But here is another error (maybe typo error only?)
<% #users.each do |user| %>
<%= user.firstname # not #user here! %>
<% end %>

Resources