I have an application that allows users to save events. I would like to be able to see which events are being saved the most over the past week. To do this, I created a ‘trending’ function in my Event model and then tried accessing that in my view. That returns an error.
_trending.html.erb:
missing attribute: is_public
Extracted source (around line #3):
1:
2: <%
3: events = Event.trending( :timespan => 1.week, :limit => 25 )
4: %>
This is the trending function in my event model. I decided to code it in raw SQL (postgres db) so there would be no confusion about how ActiveRecord is building my query.
event.rb:
def self.trending(options={})
limit = options[:limit]
span = options[:timespan]
earliest_save = (Time.now - span)
event_sql = %( SELECT events.title, saved_events.event_id, COUNT(user_id) as save_count, MAX(saved_events.created_at) as created
FROM saved_events, events
WHERE events.id = saved_events.event_id AND saved_events.is_public = TRUE AND saved_events.created_at >= '#{earliest_save}'
GROUP BY saved_events.event_id, events.title
ORDER BY save_count DESC, created DESC
LIMIT #{limit} )
find_by_sql( "#{event_sql}" )
end
So the rows that should be returned by this function should only include the fields title, event_id, and save_count. Why is it looking for is_public? I get the impression that it somehow expects an actual instance of an Event object. If that is the case, how do I rewrite this?
Update in response to questions about is_public:
is_public is definitely a column in saved_events. I did run the migration. To isolate this further, I removed the ‘AND saved_events.is_public = TRUE’ from the SQL and still got the same error. The SQL is valid, and I checked that it works in pgAdmin.
I think the issue stems from the way find_by_sql works, as documented in the API.
I rewrote the query the Rails-way™ and was able to get rid of the SELECT statement. This code worked perfectly.