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.
source to share
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
.
source to share