Sorting issues on Heroku - ruby-on-rails

I've got the following that works fine on my local machine (running a MySQL DB) but on Heroku the sort order is wrong, instead of 1,2,3,4,5...11,12,13 etc I get 1,11,12,13,2,3,4,5...!
<% #release.releases_tracks.sort { |a,b| a.position <=> b.position }.each do |releases_track| %>
<tr>
<td><%= releases_track.position %></td>
<td><%= releases_track.track.name %></td>
<td><%= releases_track.track.artists.map { |a| a.name}.join (", ") %></td>
<td><%= releases_track.track.isrc %></td>
</tr>
<% end %>
I thought is was because my position column was a varchar, but i've changed to integer, migrated the db on Heroku and it's still doing it! What's going on?

It looks like the column is still varchar or string. Can you get on the console on Heroku to load an object from the table and inspect the field to make sure if it has indeed changed to integer?
At first, I thought this might have been caused by the difference between mySql and Postgres that Heroku uses, but I do not think that's the case here.
Also, you could use ActiveRecord to handle the sorting...
results = YourModel.where('blah...blah..').order('id desc')

Related

Using Heroku, Rails sort is incorrect on updated_at timestamp column

I have a Rails 4.0 APP using PostgreSQL on Heroku. I am trying to display a table that is my XLog or transaction log, showing the last five entries in reverse order by updated_at timestamp. This works correctly on my local system. When I push it to Heroku, it sorts incorrectly.
I have checked the Heroku database definitions and the column is correctly listed as a timestamp. I have cloned the Heroku code back to my machine and verified that it is the same as what I pushed. At this point, I don't know why it doesn't work on Heroku when it works locally. And advice would be appreciated.
FWIW, the remote database and local database do not have the same data.
The code is: (Last line of log_sort was added to act as a breakpoint that would still pass the correct result.)
def self.last_objects object, count
logs = XLog.where(object: object).last(count)
log_sort = logs.sort_by{|log| log.updated_at}.reverse
log_sort
end
During execution to the breakpoint, you can see the variables passed:
This is the local result with the correct sort:
This is the Heroku result with the incorrect sort:
This is the Heroku PostgreSQL table definition for updated_at:
EDIT: View:
<% xlog = xlog_last(car.stock_number, 5) %>
...
<% xlog.each do |log| %>
<tr>
<td><%= log.associate %></td>
<td><%= log.proxy %></td>
<td><%= log.action %></td>
<td><%= log.status %></td>
<td><%= log.message %></td>
<td><%= log.value %></td>
<td><%= log.updated_at %></td>
</tr>
<% end %>
Helper:
def xlog_last(object, count)
XLog.last_objects object, count
end
EDIT:
I modified the sort_by to use an order method as follows. The results did not change at all. The same sorting error occurred and the exact same data was displayed in the exact same way:
New code:
def self.last_objects object, count
logs = XLog.where(object: object).order(updated_at: :desc).first(count)
end
I believe you need to use order to influence the actual sql query. Right now you are using sort_by which is sorting the data after you read in from the database. The order in the db is based on how it was inserted and could be different from heroku and your local system. When you export from heroku, and then import it, the ordering of the tables probably changes too.
A gem was incorrectly sorting the view. Correcting that issue fixed the problem. Still unsure why it didn't show in test except possibly for the data differences.

Weird rails pluralization issue

I have a ruby on rails application that recently started giving me issues.
I believe there may be a weird bug/feature in the way rails is pluralizing model names for the database.
For example,
I have a model called DiagExerciceWeekFive. The table in the database is called diag_exercice_week_fives. The pluralization works correctly here.
I think there may be a problem in the way rails is attempting to "de-pluralize" the table into the respective objects.
When I try to load up a simple form that displays all of my diagweekfives, I get this error:
uninitialized constant Diag::DiagExerciceWeekFife
Not once have I used that name in my application.
Here's the relevant bit of code that is throwing the error:
<% ExerciceWeekFive.all.each do |exercice| %>
<tr class="success">
<td><%= check_box_tag :exercices_week_five_ids, exercice.id, #diag.exercices_week_fives.include?(exercice), :name => 'diag[exercices_week_five_ids][]' %></td>
<td><%= exercice.number %></td>
<td><%= exercice.description %></td>
</tr>
The exception is thrown on the first <td> within the <tr>
Has anyone run into this before? I know little about rails, but I am trying to maintain some legacy code.
Thanks.

Make method work with activerecord grouped objects

I have a bunch of objects, and I grouped them by the day they happened.
scope :grouped_by_user_with_total_time, lambda {
group(:user_id, :day).select('user_id, SUM(time_worked) AS time_total, day, editable, approvable, accepted, comments')
}
I also have some methods that change editable, approvable, and accepted. But now since they are grouped, I get this error when trying to approve grouped objects.
Couldn't find TimeLog without an ID
My approve method:
def approve
#time_logs = []
t = TimeLog.find(params[:time_logs])
if t.instance_of?(Array)
#time_logs = t
else
#time_logs << t
end
end
What do I have to change so that the methods can work on all of the hourlogs that are grouped together?
<% #time_logss.each do |timelog| %>
<% if timelog.user_id != current_user.id %>
<tr>
<!--<td><%# check_box_tag 'accept' %></td>-->
<td><%= timelog.id_name %></td>
<td><%= timelog.day.strftime("%B %d, %Y") %></td>
<td><%= timelog.time_total %></td>
<td><%= timelog.state %></td>
<% if timelog.state == "Submitted" %>
<td><%= link_to "Approve", approve_time_sheets_path(time_sheets: timelog), method: :put %></td>
You are trying to combine an aggregate function with the need to access unique data. When you use .select(''), you are telling AR which fields to populate into the object (even attributes that do not exist directly in the database).
If you add in time_logs.*, you'll lose the aggregate on time_worked, since you'll then be forced to add id to the group clause.
What you need to do have 1 instance var with the time_logs and one with the aggregate data:
#time_logs = TimeLog.all
#time_totals = TimeLog.grouped_by_user_with_total_time
Then, in the view, you can pluck out the correct total for each time_log. Although, I'm not clear on how you will be able to relate the specific time_log with it's aggregate equivalent.

Undefined Method, across classes, for a database derived field

I'm aware that variants of this question have been asked before, but I do believe my question is different ;-)
I have 2 Ruby on Rails classes (with assoc. controllers, models, etc). These are Devices and Messages.
In the Devices index.html view, I need to make reference to the newest Message record.
<table>
<tr>
<th>Device Name</th>
<th>Checked</th>
</tr>
<% newestMessage = Message.find(:all, :order => "updated_at DESC", :limit => 1) %>
<% #devices.each do |device| %>
<tr>
<td><%= device.name %></td>
<td><%= newestMessage.updated_at %></td>
</tr>
<% end %>
</table>
(I believe I should move the logic to a helper, but for the time being I'm keeping it as simple as possible while I get it working)
When I access this blahblah.com/devices, I get...
undefined method `updated_at' for #<Array:0x103f36c00>
Due to the line,
<td><%= newestMessage.updated_at %></td>
Now, I've seen questions like this that suggest to add the equivalent of the following to messages_controller.rb,
attr_accessor :updated_at
However, I've tried this and it doesn't help. Also, I don't think this should be necessary anyway as 'updated_at' is derived from the database, built with scaffold, etc.
If I just print 'newestMessage' it seems to have a sensible value.
My question is, how should I access fields within newestMessage, which are of class Message from the Device index.html.erb?
Thanks in advance.
Try newestMessage = Message.last then newestMessage.updated_at

Rails: undefined method `strftime' for nil:NilClass, but value (without strftime) returns OK

I have an odd problem with a (rails 3) activerecord query.
If I submit query #1 (below) to the view (below) everything works fine...but if I submit query #2 (below), I get "undefined method `strftime' for nil:NilClass"
...However, if I strip the strtime string away from query #2, it returns the unformatted time just fine.
"Professional specialties" is a has_many :through table; I'm assuming that has something to do with it...but I can't quite figure out what.
Any idea what's going on? All suggestions appreciated:
Query #1 (works fine)
#professionals = Professional.all(:include => :user, :conditions => ["users.first_name = ? AND users.last_name = ?", params[:name][:first], params[:name][:last]])
Query #2 (breaks strtime)
#professionals = Professional.all(:include => [:user, :professional_specialties], :conditions => ["professional_specialties.profession_type_id = ?", params[:profession_type]] )
View
<% #professionals.each do |p| %>
<tr>
<td><%= link_to("%s %s" % [p.user.first_name, p.user.last_name], p) %></td>
<td><%= p.business %></td>
<td><%= p.user.role.name %></td>
<td><%= p.user.created_at %></td>
<td><%= p.user.last_sign_in_at.strftime("%Y") %></td>
</tr>
<% end %>
My best guess would be that the two queries give you different resultsets. In the second resultset, one or more of the users has a NULL value for the last_sign_in_at column.
Run Professional.all(...).map(&:users) in the Rails console (rails console in your application directory), and double-check that they all have valid timestamps.

Resources