distance_of_time_in_words with ActiveRecord TimeWithZone - ruby-on-rails-3

I'm trying to use distance_of_time_in_words (Rails 3) on a created_at column of an ActiveRecord object.
But I get
ActiveSupport::TimeWithZone can't be coerced into Fixnum
when I call
distance_of_time_in_words(#user.created_at)
Any ideas?

You need to supply the to_time as well. Assuming you want to know "how long ago from right now":
<%= distance_of_time_in_words(#user.created_at, Time.now) %>
Alternatively, you could just do this:
<%= distance_of_time_in_words_to_now(#user.created_at) %>

Related

Rails 3 Date format in forms

My question is similar to this SO problem, but it does not answer my question:
Rails 3 default datetime format without UTC
I understand that I can add
Time::DATE_FORMATS[:default] = "%Y/%m/%d"
to my environment.rb and it will change my default time format accordingly.
So when I do Time.now.to_s I get the correct format.
However, my question is, how come this does not work with a form_builder. For example:
<%= f.text_field :date %>
will return a full UTC timestamp: 2013-01-25 07:45:21
I am aware that I can do this
<%= f.text_field :date, :value => #post.date.to_s %>
And it will give me the correct format.
But this solution seems hacky to me. Is this really the only way to do it?
I am not 100% sure. But the answer is most likely no. The rails formhelper just gives you whatever value that is in your database.
Here is where the value is retrieved for your reference:
http://api.rubyonrails.org/classes/ActionView/Helpers/InstanceTag.html#method-i-to_input_field_tag
There is no special processing of it, such as localize or to_s, which is where formatting is applied.
If the date looks like a timestamp (2013-01-25 07:45:21 UTC),
You could do something like the following to views you localize timestamps with:
<%= localize(#post.date, :format => :long) %>
According to your problem, you could try using date_select rather than text_field.
<%= f.date_select :date, :order => [:day, :month, :year] %>

Rails STI Mystery - Why does type change from Class to String in view?

This is long so I hope you'll bear with me...
I have a model called Update with two subclasses, MrUpdate and TriggeredUpdate. Using single-table inheritance, added type field as a string to Update.
In my view I'm checking which type it is to decide what to display. I assumed since type is a string, I should do
<% if #update.type == 'MrUpdate' %>
This failed, i.e., it evaluated to false when the update was an MrUpdate. I noticed that at this point, #update.type.type is Class. OK, whatever, thought I, so I changed it to:
<% if #update.type == MrUpdate %>
and it worked, i.e., the comparison evaluated to true when the update was an MrUdpate. Then I did it again lower down in my view and it failed again (i.e., it evaluated to false when the update was an MrUpdate.)
Turns out the culprit is a couple of <%= link_to ... %> calls I use and make into buttons with jQuery. If I put this code in my view:
<br>
<%= #update.type.type %><br>
<%= #update.type %><br>
<%= link_to 'New Note', new_note_path(:update_id => #update.id), :class => "ui-button" %>
<br>
<%= #update.type.type %><br>
<%= #update.type %><br>
What I see is:
Class
MrUpdate
(the New Note button)
String
MrUpdate
It's changing from a class to a string! So what the heck am I doing wrong or missing here? Why should a link_to do that? First I'm not clear why it's not a string in the first place, but then really confused as to why it would change...?!? Any help or explanation would be helpful. I can just code it one way at the top and another way at the bottom, but that way madness lies. I need to understand why this is happening.
I figured out what the issue is here. Thanks to fl00r for pointing the way.
Yes, type is a reserved in Ruby 1.8.7 which tells you the class of the object you call it from. But it's also true that it is the name of the field used in Rails to indicate single-table inheriance and to store the name of the class of each instance of the subclass.
So I naively tried to access the value of the type field using #update.type. But what this was doing at the top of the view was calling the type method of the Object class in Ruby. For whatever reason, after the link_to calls, it was then access the value of the type field of the updates table.
While trying to figure this out I called #update.type in the Rails console and saw this message: "warning: Object#type is deprecated; use Object#class". Finally it registered what I was doing. When I changed my calls to:
<% if #update.class == MrUpdate %>
everything works as expected. I never saw a call to determine the type in any of the pages I found via Google about STI. This despite the fact that they all recommended using only one controller, wherein sometimes you must need to determine the class of the instance you have.
So, dumb mistake--pilot error. But maybe this will help someone else who gets tripped up on this.

Does MongoID do a separate query for .count(true)?

I have a ruby on rails 3 project in which I query for a certain number of objects by using a .limit(3) . Then, in my view, I loop through these objects. After that, if there are 3 objects in the view, I display a "load more" button. Here is the view code:
<% #objects.each do |object| %>
<%= render object._type.pluralize.underscore + '/teaser', :object => object %>
<% end %>
<% if #objects.size(true) == 3 %>
#load more link here
<% end %>
The size(true) is passed a boolean to ensure that mongoID takes into account the .limit and .offset on my query (otherwise it returns the total number of objects that matched, regardless of the limit / offset). Here are the relevant development log lines:
MONGODB project_development['system.indexes'].insert([{:name=>"_public_id_1", :ns=>"project_development.objects", :key=>{"_public_id"=>1}, :unique=>true}])
MONGODB project_development['objects'].find({:deleted_at=>{"$exists"=>false}}).limit(3).sort([[:created_at, :desc]])
#some rendering of views
MONGODB project_development['system.indexes'].insert([{:name=>"_public_id_1", :ns=>"project_development.objects", :key=>{"_public_id"=>1}, :unique=>true}])
MONGODB project_development['$cmd'].find({"count"=>"objects", "query"=>{:deleted_at=>{"$exists"=>false}}, "limit"=>3, "fields"=>nil})
My question is: does MongoID do a separate query for my #objects.size(true)? I imagine the ['$cmd'] might indicate otherwise, but I'm not sure.
I don't think so, there was a pull request month ago to add aliases for :size, :length to :count to avoid re-running queries. You can check that.

Rails 3 - how to work with data got from database

I am loading from database the only row. The data are stored in variable (e.g.) #data.
In view, if I want to display the value got from database, I have to do following:
<% #data.each do |d| %>
<%=d.name %>
<%end%>
And I would like to ask you - exist any better way? I think it's a bit silly for the only row to use loop... I tried something like
<%= #data.name %>
OR
<%= #data.each.name %>
But in both cases I got the error message about bad syntax...
So to my question - is possible to get display data a bit more elegantly?
EDIT: my query: #data = Car.includes(:tyres).where("param1 = ?", params[:param1])
If you've loaded more than one model (row), then a loop is the natural construct for displaying each value. If you're really set on a one-liner, you could use some of Ruby's list comprehensions:
<%= #data.map(&:name).join(" ") -%>
I think that you are loading .all instead of .first.
In your controller,
#data = Data.where(:some => 'condition').first
or
#data = Data.find(params[:id])

problem with datetime field in Rails model

I have a problem with datetime attribute in Rails model.
model:
attr_accessor :from, :to, :via, :datetime
erb template:
<%= f.text_field :from %>
<%= f.text_field :to %>
<%= f.text_field :via %>
<%= f.datetime_select :datetime, :discard_year => true %>
I got:
#datetime(4i)' is not allowed as an instance variable name
On this line: #search_form = SearchForm.new params[:search_form]
What's wrong?
I don't know exactly what's causing the error, but I can tell you that to fix it, you'll need to change the attribute name datetime to, say sent_on (most anything else, really).
Why the error? I'd guess it's because datetime is a data type in SQL, and thus shouldn't be used as a column name, but the error seems to be coming from ruby - either your model or ActionView, so I'm not sure if that supports my theory...
Anyway, hope this helps!
Update: I just tested it, and you can use "datetime" as a column name in SQL (MySQL, at least). There goes that theory - it's a Rails thing, then, I guess...