如何避免ActiveRecord_Relation的未定义方法`id'?

时间:2017-06-25 11:15:46

标签: ruby-on-rails ruby activerecord

希望这不是一个重复的问题,因为我花了几周时间搜索StackOverflow以获得答案,并且没有找到解决我问题的方法。

我有一个Ruby on Rails API(Ruby 1.9.3,Rails 4.0.0),我正在使用ActiveRecord与我们的数据库进行交互。当请求检索当前安排的横幅时,它完美地工作。但是,如果没有安排横幅广告,则会遇到500响应:

undefined method `id' for #\u003cBanner::ActiveRecord_Relation:0x0000000628fba8\u003

我的理解是,这是因为在“nil”上尝试了一种固有的“id”方法,这是在没有找到合格记录时数据库查找的结果。如何优雅地处理这种情况,以便不会遇到500错误,以便我可以向请求者返回更礼貌的回复?

这是我的控制器:

class BannersController < ApplicationController
  load_and_authorize_resource

  respond_to :json

  # Look to see if any banners should be showing right now
  def current
    @banner = Banner.current
  end
end

这是我的模特:

class Banner < ActiveRecord::Base
  self.table_name   = 'Banner'
  self.primary_key  = :BannerID

  alias_attribute :name,              :FriendlyName
  alias_attribute :banner_html,       :BannerHtml
  alias_attribute :banner_image,      :BannerImage
  alias_attribute :start_date,        :StartDate
  alias_attribute :end_date,          :EndDate
  alias_attribute :is_active,         :IsActive
  alias_attribute :is_removed,        :IsRemoved
  alias_attribute :start_date_time,   :StartDateTime
  alias_attribute :end_date_time,     :EndDateTime
  alias_attribute :hidden_text,       :HiddenText
  alias_attribute :hidden_background_color,       :HiddenBackgroundColor

  # This returns nil if no banner is scheduled, which then causes the view to return a 500 response because it tries to invoke an "id" method
  scope :current, -> { Banner.where("StartDateTime <= ? AND EndDateTime >= ? AND IsActive=1 AND IsRemoved=0 AND BannerType=1", Time.now.to_s(:db), Time.now.to_s(:db)).first }  
end

注意:我尝试过使用.find_by并尝试不使用.first,但似乎仍无法找到解决方法。

以下是我的观点:

json.extract! @banner, :id, :banner_html, :banner_image, :hidden_text, :hidden_background_color

json.request_id request.uuid

数据库表“Banner”的主键为“BannerID”。

感谢所有愿意花时间研究这个问题的人。我花了无数个小时阅读并尝试一切以纠正这种情况,但无济于事。

2 个答案:

答案 0 :(得分:1)

  

未定义的方法`id&#39; for \ u003cBanner :: ActiveRecord_Relation:0x0000000628fba8 \ u003

     

数据库表&#34; Banner&#34;有一个主键是&#34; BannerID&#34;

然后乳清仍在使用:id!变化

json.extract! @banner, :id, :banner_html, :banner_image, :hidden_text, :hidden_background_color

json.extract! @banner, :BannerID, :banner_html, :banner_image, :hidden_text, :hidden_background_color

小注:

按照惯例,属性应该在snake_case

答案 1 :(得分:0)

为什么不是

if !@banner.blank?
  json.extract...
  ...
else
  json.null!
  (or whatever you want?)
end