【问题标题】:How to avoid undefined method `id' for ActiveRecord_Relation?如何避免 ActiveRecord_Relation 的未定义方法“id”?
【发布时间】:2017-06-25 11:15:45
【问题描述】:

希望这不是一个重复的问题,因为我已经花了数周时间在 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”。

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

【问题讨论】:

  • 尝试在json.extract! 行中将:id 更改为:banner_id
  • 什么是ActiveRecord_Relation

标签: ruby-on-rails ruby activerecord


【解决方案1】:

\u003cBanner::ActiveRecord_Relation:0x0000000628fba8\u003 的未定义方法“id”

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

那么乳清仍在使用: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

【讨论】:

  • 非常感谢您的帮助!我是 Ruby 新手,你的帮助是救命稻草。当我做出您建议的更改时,我现在收到以下回复:undefined method 'BannerID' for #\u003cBanner::ActiveRecord_Relation
  • @RavingHermit 表中的字段名称是什么?是BannerID 还是banner_id
  • 表字段为数据库中的BannerID。
【解决方案2】:

你为什么不直接

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

【讨论】:

  • 我闻到你在煮什么,我很喜欢。不幸的是,我仍然遇到同样的错误:undefined method 'id' for #\u003cBanner::ActiveRecord_Relation:0x00000007134640\u003e
  • 这是我的更新视图:if !@banner.blank? json.extract! @banner, :id, :banner_html, :banner_image, :hidden_text, :hidden_background_color json.request_id request.uuid else json.null! end
  • 另一种处理它的方法,实际上可能会更好,将有一个返回“默认”不可用横幅的 model.method,并在控制器中检查:@banner = Banner.current like you have but followed by @banner = Banner.default unless @banner跨度>
猜你喜欢
  • 1970-01-01
  • 2016-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多