1

I have a lot places where the following pattern emerges. The case is that I need to prefill an attribute with "random" information, unless it is provided by a consumer of the Model.

class Server
  validates :fqdn, presence: true

  before_validation prefill_fqdn, if: :must_prefill_fqdn?

  private
  def must_prefill_fqdn?
    #what best to check against?
  end
  def prefill_fqdn
    self.fqdn = MyRandomNameGenerator.generate
  end
end

I am looking for what to check against:

  • nil? is rather limited and excludes values like "". It checks if it is nil, not whether it was set by a consumer.
  • empty? catches more, but still does not match the requirement of "unless provided by the consumer", what if a user provides ""? It also renders the validate presence: true pretty much useless: it will never be invalid.
  • fqdn_changed? seems to match best, but its name and parent class (ActiveModel::Dirty suggests that this is not the proper test either. It is not changed but rather provided. Or is this merely semantic and is changed? the proper helper here?

So, what is the best test to see "if a consumer provided an attribute". Providing can be either in Server.new(fqdn: 'example.com') (or create or build. Or through one of the attribute-helpers, such as fqdn= or update_attribute(:fqdn, 'example.com') and so on.

berkes
  • 26,996
  • 27
  • 115
  • 206

1 Answers1

0

You could test whether the params are present like so: params[:param_name].present?

The present? method (inverse of blank?) tests for empty? but also returns false for whitespace so that '', ' ', nil, [], and {} are all false.

An improvement on this would be to use the presence method. Then you could do this directly in your controller method without the need for callbacks:

fqdn = params[:fqdn].presence || MyRandomNameGenerator.generate
benjaminjosephw
  • 4,369
  • 3
  • 21
  • 40
  • Thanks. However, presence, like `blank?` or `empty?` don't really match the requirement "unless set by a consumer". If a consumer does `Server.new(fqdn: " ")` it should not prefill it, but, instead, return the validation error; in other words: `presence? == false` does not mean "it was not set by a user". – berkes Jan 30 '14 at 16:50
  • I see. Perhaps then the problem could be solved by changing the UI. How about giving users the choice between custom content or randomly generated content? That way you can treat all entered content as "set by the customer" and validate accordingly. It also has the added advantage of letting the user know what to expect. – benjaminjosephw Jan 30 '14 at 17:11
  • 1
    Also, I just realised you're creating a API rather than a web interface here. In which case, why not just set a default value, then let the user update it? (see - http://stackoverflow.com/a/5127684/2463468) – benjaminjosephw Jan 30 '14 at 17:19
  • 1
    Thanks. My question is answered perfectly with the link you just posted. And, indeed, this is a RESTfull JSON api. – berkes Jan 30 '14 at 18:37