Coffee Bite
Coffee Bite

Reputation: 5164

How do I set a value of a nil field just before save in mongoid?

I have a mongoid model, say Webpage, which is like this:

class Webpage
  include Mongoid::Document

  field :short_link, type: String
  field :actual_link, type: String

  before_save :generate_short_link

  protected

  def generate_short_link
    short_link ||= rand(36**8).to_s(36)
  end
end

But when I do Webpage.create, the short_link is not automatically populated. What am I doing wrong?

Upvotes: 0

Views: 3640

Answers (3)

ksol
ksol

Reputation: 12235

I'm a bit of a moron when it comes to callbacks, especially when it's something like "updating/setting a field before the object is saved". I found that using before_validation make these kind of errors go away, at least the few times I tried. Though I'd like at some point to understand why, what did I miss with regular callbacks & what did I do wrong.

Upvotes: 0

Paul Hoffer
Paul Hoffer

Reputation: 12906

According to the Mongoid docs for Callbacks, it only fires the callback of the action you are executing. That is why it is not firing. You would need to do as Voldy answered, use the before_create callback.

However, if that is all the you are doing (your code is not more complicated), then instead of setting short_link if it was not assigned already, you could just set that as the default like this:

class Webpage
  include Mongoid::Document

  field :short_link,  type: String,  default: -> { rand(36**8).to_s(36) }
  field :actual_link, type: String

end

This will behave the same as your current code is intended to.

Upvotes: 1

Voldy
Voldy

Reputation: 12868

It seems that you need to populate a short_link only on create and it is better to use before_create callback.

class Webpage
  include Mongoid::Document

  field :short_link, type: String
  field :actual_link, type: String

  before_create :generate_short_link

  protected

  def generate_short_link
    self.short_link = rand(36**8).to_s(36)
  end
end

Upvotes: 1

Related Questions