【问题标题】:In Ruby on Rails, how do I assign a default value to a member_of member of an ActiveRecord object?在 Ruby on Rails 中,如何为 ActiveRecord 对象的 member_of 成员分配默认值?
【发布时间】:2011-12-28 00:17:12
【问题描述】:

我是 ruby​​ on rails 的新手,我继承了一个代码库。现在我无法在我的应用程序中创建新的用户帐户,当我尝试时收到以下错误:

Users::RegistrationsController#create 中的 NoMethodError

nil:NilClass 的未定义方法“名称” Rails.root: /home/nathan/dev/legwork-core

应用程序跟踪 |框架跟踪 |全跟踪 app/models/contact.rb:74:in block (2 levels) in <class:Contact>' app/models/user.rb:31:inupdate_contact'

调用代码在这里:

  searchable do
    string :category do
      self.category.name
    end
  end

Category 应该是 ContactCategory 的一个实例,我认为我需要将 self.category 设置为默认值(如果它为零)。我试过这个来解决它:

  after_initialize :set_defaults

  def set_defaults
    self.category = ContactCategory.first if self.category.nil?
  end

我也试过了:

  def after_initialize
    self.category = ContactCategory.first if self.category.nil?
  end

我已经试过了:

  before_create :set_defaults

  def set_defaults
    self.category = ContactCategory.first if self.category.nil?
  end

有人建议将此逻辑放在 before_save 中,但已经有一个 before_save 包含此逻辑,这就是我看到作者最初打算成为默认值的地方。

更新:

现在我明白了问题所在,这个问题很愚蠢。我假设赋值语句从未运行,因为我假设 ContactCategory.first 也不为零。可悲的是,这里的一切都按预期工作。这个故事的寓意是:

我用来设置默认值的所有钩子都正常工作。我建议使用它们使用 ActiveRecord 设置默认值。

【问题讨论】:

  • 你能告诉我们数据库结构吗?描述表?目前您正在使用“名称”,但该字段似乎不存在。
  • 这就是用户中的 NoMethodError::RegistrationsController#create undefined method `name
  • 真正的问题是类别为零:undefined method 'name' for nil:NilClass
  • 我以为是类别没有被分配,所以 nil 没有名为“name”的方法。

标签: ruby-on-rails ruby activerecord


【解决方案1】:

我倾向于使用before_create 回调来设置默认值等等,但here's the full list of ActiveRecord callbacks from the RoR API docs。您会注意到 after_initialize 并不像其名称所暗示的那样工作:

最后,一个 after_findafter_initialize 回调会为查找器找到并实例化的每个对象触发,after_initialize 也会在新对象实例化后触发。

您可能想改用before_savebefore_create

【讨论】:

  • 感谢您的回复,我无法投票,因为我缺乏声誉。我刚刚尝试使用 before_callback 并且得到了相同的结果。已经有一个 before_save 里面有这个逻辑,这就是我看到作者最初打算成为默认值的地方。
  • 也许您需要保存类别 ID 来代替? self.category_id = 1 之类的东西?
  • 你能详细解释一下吗?使用表中的 ID 并以某种方式手动加载 ContactCategory 对象?
  • 我不确定您是如何建立关系的,但通常外键是一个 ID。因此,如果Something has_one 联系,那么Something 将有一个名为contact_id 的字段,当您调用something.contact 时,Rails 会隐式使用该字段。
  • 当我进行实验时,结果发现所有的钩子都按照您建议的方式运行。问题是 ContactCategory.first 由于某种原因也为零。
【解决方案2】:

另外,请记住,您也可以在迁移中指定默认值(并确保该字段永远不会为 NULL)。 Here's an example from one of my own projects:

class AddRolesMaskToUsers < ActiveRecord::Migration
  def self.up
    add_column :users, :roles_mask, :integer, :default => DEFAULT_ROLE, :null => false
  end
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 2017-04-04
    • 2012-07-08
    相关资源
    最近更新 更多