我有一个允许用户保存事件的应用程序。我希望能够看到过去一周内哪些事件被保存得最多。为此,我在我的Event模型中创建了一个'趋势'功能,然后尝试在我的视图中访问它。这会返回错误。
_trending.html.erb:
missing attribute: is_public
Extracted source (around line #3):
1:
2: <%
3: events = Event.trending( :timespan => 1.week, :limit => 25 )
4: %>
这是我的活动模型中的趋势功能。我决定用原始SQL(postgres db)编写代码,这样就不会混淆ActiveRecord如何构建我的查询。
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
因此,此函数应返回的行应仅包含字段title,event_id和save_count。为什么要寻找is_public?我得到的印象是它以某种方式期望一个Event对象的实际实例。如果是这种情况,我该如何重写呢?
针对有关is_public:的问题进行更新 is_public绝对是saved_events中的一列。我确实进行了迁移。为了进一步隔离,我从SQL中删除了'AND saved_events.is_public = TRUE',但仍然遇到了同样的错误。 SQL是有效的,我检查它是否在pgAdmin中工作。
答案 0 :(得分:1)
我认为问题源于find_by_sql的工作方式,如API中所述。
如果调用跨越多个表的复杂SQL查询,则SELECT指定的列将是模型的属性,无论它们是否是相应表的列。 http://apidock.com/rails/ActiveRecord/Base/find_by_sql/class
我重写了Rails-way™的查询,并且能够摆脱SELECT语句。这段代码完美无缺。
time_range = (Time.now - span)..Time.now
joins(:saved_events).where( :saved_events => { :created_at => time_range, :is_public => true } )
.group( "saved_events.event_id, events.id" )
.order( "COUNT(saved_events.user_id) DESC, MAX(saved_events.created_at) DESC" )
.limit( limit )
答案 1 :(得分:0)
Nodrog是对的,它正在寻找is_public。 你有没有进行迁移? (并在生产时重新启动),如果该列不存在则删除该行:“saved_events.is_public = TRUE”