Nathan C. Tresch
Nathan C. Tresch

Reputation: 948

In Ruby on Rails, how do I assign a default value to a member_of member of an ActiveRecord object?

I'm new to ruby on rails, and I've inherited a codebase. Right now I can't create a new user account in my application, when I try I get the following error:

NoMethodError in Users::RegistrationsController#create

undefined method `name' for nil:NilClass Rails.root: /home/nathan/dev/legwork-core

Application Trace | Framework Trace | Full Trace app/models/contact.rb:74:in block (2 levels) in <class:Contact>' app/models/user.rb:31:inupdate_contact'

The calling code is here:

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

Category is supposed to be an instance of ContactCategory, and what I think I need is to set self.category to the default if its nil. I tried this to fix it:

  after_initialize :set_defaults

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

I also tried:

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

And I've tried:

  before_create :set_defaults

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

Someone else has suggested putting this logic in before_save, but there is already a before_save that has this logic in it, that's where I saw what the author had intended to be the default in the first place.

UPDATE:

This question is silly now that I see what's wrong. I was assuming that the assignment statement never ran because I assumed ContactCategory.first was also not nil. Sadly, everything here is working as expected. The moral of the story is:

All of the hooks I was using to set the default were working correctly. I would recommend using them to set a default using ActiveRecord.

Upvotes: 2

Views: 638

Answers (2)

sczizzo
sczizzo

Reputation: 3206

Also, remember that you can assign defaults (and ensure the field is never NULL) in the migration as well. 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

Upvotes: 0

sczizzo
sczizzo

Reputation: 3206

I tend to use the before_create callback for setting default values and whatnot, but here's the full list of ActiveRecord callbacks from the RoR API docs. You'll notice after_initialize doesn't work like exactly its name suggests:

Lastly an after_find and after_initialize callback is triggered for each object that is found and instantiated by a finder, with after_initialize being triggered after new objects are instantiated as well.

You probably want to use before_save or before_create instead.

Upvotes: 1

Related Questions