Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow a default value when the attribute is assigned as nil, with the :allow_nil option #292

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

JanDintel
Copy link

This MR adds the option :allow_nil to a Virtus::Attribute. The option allows the user to specify wether to use the default value of an attribute that got assigned as nil. The option will be false by default for backwards compatibility.

See gist for before and after examples

Related issues for this MR are: #291 and #172.

…il? predicate on the Virtus::Attribute class
…the presence of the attribute on the Virtus instance given the :allow_nil option
…is assigned as nil:

- Replace the Virtus::Attribute::Accessor#defined? method for the #present? method in the Virtus::AttributeSet#skip_default? private method
- Replace the #instance_variable_defined? method for the Virtus::Attribute::Accessor#present? method in the Virtus::Attribute::LazyDefault#get method
- Update the README with the documentation of this feature

This fixes Github issue solnic#291 (solnic#291) and solnic#172 (solnic#172)
@coveralls
Copy link

Coverage Status

Coverage increased (+0.01%) when pulling a75ba02 on JanDintel:allow-nil-option into 5093278 on solnic:master.

@JanDintel
Copy link
Author

Could you have a look at this MR @elskwid?

@JanDintel
Copy link
Author

Maybe you could have a look @solnic?

@solnic
Copy link
Owner

solnic commented Sep 24, 2014

I will take a look yes! My initial reaction is "OMG NO" but maybe I'm missing something, I need to take a closer look. Will get back to you as soon as possible.

@JanDintel
Copy link
Author

@solnic Maybe it's just the name of the option (:allow_nil) that puts you off. But I think this feature/fix is a good addition to Virtus, while staying backwards compatible in the API.

@jpmoral
Copy link

jpmoral commented Feb 4, 2015

👍 This also seems related to #235.


# default from a singleton value (string in this case),
# that doesn't allow a nil value
attribute :author, String, :default => 'Mies', :allow_nil => false
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the example should use a default, because it's much less likely that you'd need to worry about nil if you've got a default.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you're suggesting to use the default if nil is passed in. Hmm. That's a harder sell.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need :allow_nil => false when you send a default?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@envygeeks Maybe this example explains it the best:

class Page
  include Virtus.model

  attribute :title, String, :default => 'New page', :allow_nil => true
  attribute :author, String, :default => 'Mies', :allow_nil => false
end

page = Page.new(title: nil, author: nil)
page.title     # => nil
page.author    # => 'Mies'

With the :allow_nil => false option, the default is used when the attributes is assigned as nil.

Edit: Just saw that I published a gist that describes the behaviour as well.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you talk more about the differences between page = Page.new(title: nil, author: nil) and page = Page.new?

@booch
Copy link
Collaborator

booch commented Nov 12, 2015

I'm inclined to accept this, or something similar. Since we don't do validations, we can't just reject the whole object if one attribute contains something that we really don't want in our object. So at this level, I suppose it makes sense to ensure our object is in a useable state, whatever that might mean.

@lime
Copy link

lime commented Oct 13, 2016

I've encountered this need a couple of times; it would be great to be able to specify that an attribute falls back to the default when set to nil.

I wonder if this would be an easier feature to pull through if the naming was more explicit? I could see how :allow_nil could be misinterpreted as to mean something different.

Something like :fallback_to_default_on_nil would be hard to misunderstand, though it's quite a mouthful. Would maybe :default_on_nil be close enough..?

@taryneast
Copy link

Bump... I'd really like this functionality

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants