How to avoid undefined `id 'method for ActiveRecord_Relation?

Hopefully this is not a duplicate question, as I spent weeks cleaning StackOverflow for answers and found no solution to my problem.

I have a Ruby on Rails API (Ruby 1.9.3, Rails 4.0.0) and I am using ActiveRecord to interact with our database. When a request is made to get the currently scheduled banner, it works fine. However, when there is no scheduled banner, 500 responses arise:

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

      

My understanding is that this is because the "id" method is used on a "nil" basis, which is the result of a database lookup when no matching record is found. How can I gracefully handle this scenario so that error 500 is not encountered and so that I can return a more polite response to the requester?

Here is my controller:

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

      

Here is my model:

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

      

Note. I tried using .find_by and also tried not to use .first but still can't find permission to do this.

Here is my view:

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

json.request_id request.uuid

      

The "Banner" database table has a primary key "BannerID".

Thanks to everyone who would take the time to do this. I've spent countless hours reading and tried everything to fix the situation, but to no avail.

+3


source to share


2 answers


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

The "Banner" database table has a primary key "BannerID"

Then the serum uses :id

more !. Change

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

      

to



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

      

Small note:

By convention, attributes must be in snake_case

.

+1


source


Why would you just



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

      

0


source







All Articles