Undefined Method Error for strftime in Rails 3 - ruby-on-rails

I just started learning Rails, I'm having trouble trying to format a time. I have a Ticket model which has many contact logs, and I want to format the created_at timestamp in a view. When I use this code:
<% #contacts.each do |contact| %>
<p><%= contact.created_at.strftime("%B %e, %Y") %></p>
<p><%= contact.author %></p>
<p><%= contact.description %><p>
<% end %>
to print out the contacts associated with a ticket, the page displays the error:
undefined method `strftime' for nil:NilClass
However, when I use
<% #contacts.each do |contact| %>
<p><%= contact.created_at %></p>
<p><%= contact.author %></p>
<p><%= contact.description %><p>
<% end %>
a date is printed (something like 2012-08-26 05:16:15 UTC), along with the expected values for author and description.
I've looked at all of the timestamp values for the contact objects in my database, and none have created_at values of anything other than times. Can anyone help me out with this?

Perhaps one of your records has created_at set to nil, Try this:
<p><%= contact.created_at.present? ? contact.created_at.strftime("%B %e, %Y") : contact.created_at%></p>

created_at could return not only string.
Did you tried this:
<%= contact.created_at.to_s.strftime("%B %e, %Y") %>?

Related

How to fix error in rails

This is the error I am encountering and I was wondering how I can fix it. I'm new to rails and I didn't think that .each was a method. If some one could please help me it would be very apreciated. thanks
undefined method `each' for nil:NilClass
this is the code that i am getting the error on.
<h1>Portfolio Items</h1>
<% #portfolio_items.each do |portfolio_item| %>
<p><%= portfolio_item.title %></p>
<p><%= portfolio_item.subtitle %></p>
<p><%= portfolio_item.body %></p>
<%= image_tag portfolio_item.thumb_image unless portfolio_item.thumb_image.nil? %>
<% end %>
Welcome to SO.
Either you have not set the var #portfolio_items or its mis-spelled.
If you have defined it then at least it should have had Array like data structure And prevented this error.
Some of the array like objects will be ActiveRecord::Associations::CollectionProxy
In ruby undefined #instance vars are set with nil and no error is raised.
If this does not help, please update your question with more details and I will update this answer.
If you do:
[nil].each{|e| p e}
=> nil
You can see there's an element inside the array, so you can use each, you can iterate and print its content, and you'll see there's a nil value inside.
If in the other hand you write:
nil.each{|e| p e}
You'll get the error:
undefined method `each' for nil:NilClass (NoMethodError)
That's to say there's no each method available between all the methods that can be applied to nil.
In your code, in the controller most probably, you're defining #portfolio_items, but for some reason, this isn't taking the value you want, it's getting a nil value, so when you try to iterate over it, you get that error.
You code is expecting #portfolio_items to be an array, but either #portfolio_items is not assigned a value or assigned a nil in the controller action.
your list is nil, you can do an if...else check to handle it on your view template
<h1>Portfolio Items</h1>
<% if #portfolio_items.count == 0 %>
<p>There are no items</p>
<% else %>
<% #portfolio_items.each do |portfolio_item| %>
<p><%= portfolio_item.title %></p>
<p><%= portfolio_item.subtitle %></p>
<p><%= portfolio_item.body %></p>
<%= image_tag portfolio_item.thumb_image unless portfolio_item.thumb_image.nil? %>
<% end %>
<% end %>
You can try use :
(#portfolio_items || []).each do |portfolio_item|
The instance variable #portfolio_items is nil and each loop over nil is throw error.
So follow below code:
<h1>Portfolio Items</h1>
<% if #portfolio_items.nil? %>
No Item to display.
<% else %>
<% #portfolio_items.each do |portfolio_item| %>
<p><%= portfolio_item.title %></p>
<p><%= portfolio_item.subtitle %></p>
<p><%= portfolio_item.body %></p>
<%= image_tag portfolio_item.thumb_image unless portfolio_item.thumb_image.nil? %>
<% end %>
<% end %>

Rails - Check if record has been updated

I am trying to check whether a record has been updated/edited, and if it has, then it should display that is has been edited.
This is my if statement:
<% if comment.changed? %>
<p id="comment-name"><%= comment.user.name %>(edited)</p>
<% else %>
<p id="comment-name"><%= comment.user.name %></p>
<% end %>
Although it isn't working. When a comment is updated, no (edited) text is showing. What do I need to put in the if statement to check whether the comment record has been updated?
I don't think #changed? is doing what you think it's doing.
#changed? returns true if any attribute have unsaved changes, false
otherwise.
Reference
A record is edited if it's updated_at is different than created_at ( updated_at should be greater than created_at to be more precise).
<% if comment.updated_at != comment.created_at %>
<p id="comment-name"><%= comment.user.name %>(edited)</p>
<% else %>
<p id="comment-name"><%= comment.user.name %></p>
<% end %>

undefined method `strftime' for nil:NilClass - shows sometimes

I'm building a simple app for displaying movies using themoviedb gem. However, when I try to do a search query, it displays the error I mentioned. Now, that doesn't happen every time - only in certain cases (e.g. Matrix works fine, but Fight Club shows the error)
Here's my code:
<% #movie.each do |movie| %>
<%= link_to movie_path(movie.id) do %>
<%= image_tag("#{#configuration.base_url}w154#{movie.poster_path}") if movie.poster_path %>
<% end %>
<div class="moviesindex">
<%= link_to movie.title, movie_path(movie.id) %>
(<%= movie.release_date.to_date.strftime("%Y") %>) <br />
</div>
<% end %>
Be forgiving for realease_date if movie.release_date can be nil at times using try:
<%= movie.release_date.try(:year) %>
This will give you release year if release_date is valid and gives you nil if release_date is nil.
Since release_date, I assume is already either a Date or DateTime or ActiveSupport::TimeWithZone, the to_date is not necessary. Also I think date.year is more cleaner than date.strftime("%Y").

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.

Rails 3 - strftime

If I have a :due column that is a datetime type, how would I make calling .strftime on it work?
For instance, I have
<% #todos.each do |todo|%>
<%= todo.due.strftime("%h %d") %>
<% end %>
in my show view and I get undefined method `strftime' for nil:NilClass
I have this in my show method in the controller:
#todos = ProjectTodo.for_project(params[:id])
Note: I'm not trying to display when it was updated or created, just want to display a formatted date.
try this..
<% #todos.each do |todo|%>
<%= todo.due ? todo.due.strftime("%h %d") : nil %>
<% end %>
If the date is there then it will convert to the given format else it will display nil.

Resources