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

Remove explicit respond_to? and Validator#setup call #10716

Closed
wants to merge 7 commits into
base: master
from

Conversation

Projects
None yet
3 participants
@apotonick
Contributor

apotonick commented May 22, 2013

This moves the setup process of validators into the constructor, pushing all knowledge about this into the validator class itself. Makes it easier to override internals in subclassed validators.

remove explicit call to Validator#setup to get rid of respond_to call…
…. instead, respective validators take care of their setup.
@rafaelfranca

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca

rafaelfranca May 22, 2013

Member

Could you give us example of what you want to accomplish with this change?

Maybe an example how was the validator subclass before and after it.

Member

rafaelfranca commented May 22, 2013

Could you give us example of what you want to accomplish with this change?

Maybe an example how was the validator subclass before and after it.

@apotonick

This comment has been minimized.

Show comment
Hide comment
@apotonick

apotonick May 22, 2013

Contributor

This is the "bottom line" of my PR: apotonick@543c59d#L2L88

I could get my stuff working using the existing code. However, my main intend is to remove the respond_to? call and move stuff into Validator itself. While this simplifies the Validator interface it is also preparing some more changes I'd like to push (especially simplifying UniquenessValidator in AR).

Are you worried about the change? Is it because the options contain a :class now (I don't like it either)? It shouldn't break existing code?!

Contributor

apotonick commented May 22, 2013

This is the "bottom line" of my PR: apotonick@543c59d#L2L88

I could get my stuff working using the existing code. However, my main intend is to remove the respond_to? call and move stuff into Validator itself. While this simplifies the Validator interface it is also preparing some more changes I'd like to push (especially simplifying UniquenessValidator in AR).

Are you worried about the change? Is it because the options contain a :class now (I don't like it either)? It shouldn't break existing code?!

@rafaelfranca

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca

rafaelfranca May 22, 2013

Member

Are you worried about the change?

No. I just want to know more about the motivation of this pull request.

Is it because the options contain a :class now (I don't like it either)?

It is awkward, but it is fine to me.

It shouldn't break existing code?!

I'm not sure of this. setup(klass) is a public method and documented as part of the API (see Validator documentation). We can't just remove it.

Member

rafaelfranca commented May 22, 2013

Are you worried about the change?

No. I just want to know more about the motivation of this pull request.

Is it because the options contain a :class now (I don't like it either)?

It is awkward, but it is fine to me.

It shouldn't break existing code?!

I'm not sure of this. setup(klass) is a public method and documented as part of the API (see Validator documentation). We can't just remove it.

@apotonick

This comment has been minimized.

Show comment
Hide comment
@apotonick

apotonick May 22, 2013

Contributor

You're right! #setup! should be made private soon and called by a public #setup which will be deprecated.

def setup(*)
  deprecation_warning
  setup!
end

private
def setup!
end
Contributor

apotonick commented May 22, 2013

You're right! #setup! should be made private soon and called by a public #setup which will be deprecated.

def setup(*)
  deprecation_warning
  setup!
end

private
def setup!
end
@rafaelfranca

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca
Member

rafaelfranca commented May 22, 2013

👍

@apotonick

This comment has been minimized.

Show comment
Hide comment
@apotonick

apotonick May 22, 2013

Contributor

What is the prefered way of deprecating (and testing this)? Sorry to ask :-)

Contributor

apotonick commented May 22, 2013

What is the prefered way of deprecating (and testing this)? Sorry to ask :-)

@rafaelfranca

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca

rafaelfranca May 22, 2013

Member

Maybe:

if validator.respond_to?(:setup)
  ActiveSupport::Deprecation.warn 'The `setup` instance method is deprecated and will be removed on Rails 4.2. Define `setup!` without arguments instead.'
  validator.setup(self)
end

You can even provide a code snippet in the deprecation message to make explicit what the users have to do:

Change your setup method to:

class MyValidator < ActiveModel::Validator
  private

  def setup!
    @klass.send :attr_accessor, :custom_attribute
  end
end

To test you can define a Validator class with the setup method defined and assert the deprecation message with the assert_deprecated method when calling validates_with. Something like this:

def test_setup_is_deprecated
  assert_deprecated do
    Class.new do
      include ActiveModel::Validations

      validates_with MyDeprecatedValidator
    end
  end
end
Member

rafaelfranca commented May 22, 2013

Maybe:

if validator.respond_to?(:setup)
  ActiveSupport::Deprecation.warn 'The `setup` instance method is deprecated and will be removed on Rails 4.2. Define `setup!` without arguments instead.'
  validator.setup(self)
end

You can even provide a code snippet in the deprecation message to make explicit what the users have to do:

Change your setup method to:

class MyValidator < ActiveModel::Validator
  private

  def setup!
    @klass.send :attr_accessor, :custom_attribute
  end
end

To test you can define a Validator class with the setup method defined and assert the deprecation message with the assert_deprecated method when calling validates_with. Something like this:

def test_setup_is_deprecated
  assert_deprecated do
    Class.new do
      include ActiveModel::Validations

      validates_with MyDeprecatedValidator
    end
  end
end
@apotonick

This comment has been minimized.

Show comment
Hide comment
@apotonick

apotonick May 22, 2013

Contributor

Now the last quest: Why is options.freeze called in Validator#initialize?

@rafaelfranca I wanted to say I really appreciate your responsiveness - amazing! 😸

Contributor

apotonick commented May 22, 2013

Now the last quest: Why is options.freeze called in Validator#initialize?

@rafaelfranca I wanted to say I really appreciate your responsiveness - amazing! 😸

@josevalim

This comment has been minimized.

Show comment
Hide comment
@josevalim

josevalim May 22, 2013

Contributor

I have added some comments, :+1 for getting rid of the respond_to? in general.

Contributor

josevalim commented May 22, 2013

I have added some comments, :+1 for getting rid of the respond_to? in general.

@apotonick

This comment has been minimized.

Show comment
Hide comment
@apotonick

apotonick May 22, 2013

Contributor

Cool! I removed the automatic setup! call, I personally like that better. Ready for merge!

Contributor

apotonick commented May 22, 2013

Cool! I removed the automatic setup! call, I personally like that better. Ready for merge!

def deprecated_setup(options) # TODO: remove me in 4.2.
return unless respond_to?(:setup)
ActiveSupport::Deprecation.warn "The `Validator#setup` instance method is deprecated and will be removed on Rails 4.2. Change your `setup` method to something like:

This comment has been minimized.

@rafaelfranca

rafaelfranca May 22, 2013

Member

@apotonick should not the deprecation warning be updated to show the initialize override example?

@rafaelfranca

rafaelfranca May 22, 2013

Member

@apotonick should not the deprecation warning be updated to show the initialize override example?

@rafaelfranca

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca

rafaelfranca May 22, 2013

Member

I like it too. Just a minor comment on the deprecation message.

Member

rafaelfranca commented May 22, 2013

I like it too. Just a minor comment on the deprecation message.

@rafaelfranca

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca

rafaelfranca May 22, 2013

Member

Since it is a user facing change we will need a CHANGELOG entry, and make sure your commits are squashed.

Member

rafaelfranca commented May 22, 2013

Since it is a user facing change we will need a CHANGELOG entry, and make sure your commits are squashed.

@apotonick

This comment has been minimized.

Show comment
Hide comment
@apotonick

apotonick May 23, 2013

Contributor

Dunno how to change a PR to another branch, here it goes: https://github.com/apotonick/rails/tree/deprecate-validator-setup rebased to current rails/rails:master and including updated exception and CHANGELOG entry.

Contributor

apotonick commented May 23, 2013

Dunno how to change a PR to another branch, here it goes: https://github.com/apotonick/rails/tree/deprecate-validator-setup rebased to current rails/rails:master and including updated exception and CHANGELOG entry.

@rafaelfranca

This comment has been minimized.

Show comment
Hide comment
@rafaelfranca

rafaelfranca May 23, 2013

Member

@apotonick merged.

Thank you for contributing.

Member

rafaelfranca commented May 23, 2013

@apotonick merged.

Thank you for contributing.

@apotonick

This comment has been minimized.

Show comment
Hide comment
@apotonick

apotonick May 23, 2013

Contributor

Thank you @josevalim and especially @rafaelfranca for that quick and uncomplicated feedback and processing! ❤️

Contributor

apotonick commented May 23, 2013

Thank you @josevalim and especially @rafaelfranca for that quick and uncomplicated feedback and processing! ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment