Reputation: 31
Hopefully this is not a duplicate question, as I have spent weeks scouring StackOverflow for answers and have not found a solution to my problem.
I have a Ruby on Rails API (Ruby 1.9.3, Rails 4.0.0) and am using ActiveRecord to interact with our database. When a request is made to retrieve the currently scheduled banner, it works perfectly. When no banner is scheduled, however, a 500 response is experienced:
undefined method `id' for #\u003cBanner::ActiveRecord_Relation:0x0000000628fba8\u003
My understanding is that this is because an inherent "id" method is being attempted upon a "nil" which is the result from the database lookup when no qualifying record is found. How do I gracefully handle this scenario so that a 500 error is not encountered and so that I may 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 have tried using .find_by and also tried not using .first, but still cannot seem to find a resolution to this.
Here is my view:
json.extract! @banner, :id, :banner_html, :banner_image, :hidden_text, :hidden_background_color
json.request_id request.uuid
The database table "Banner" has a primary key of "BannerID".
Thanks to all who would take the time to look into this. I have spent untold hours reading and trying everything in order to remedy the situation, to no avail.
Upvotes: 3
Views: 367
Reputation: 2290
Why don't you just
if [email protected]?
json.extract...
...
else
json.null!
(or whatever you want?)
end
Upvotes: 0
Reputation: 33542
undefined method `id' for \u003cBanner::ActiveRecord_Relation:0x0000000628fba8\u003
The database table "Banner" has a primary key of "BannerID"
Then whey are using :id
still!. 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, the attributes should be in snake_case
.
Upvotes: 1