contracts.ruby icon indicating copy to clipboard operation
contracts.ruby copied to clipboard

rails ActiveRecord instances already have valid? method

Open nickpoorman opened this issue 9 years ago • 2 comments

I have an ActiveRecord Item class that gets returned by a method that has the following contract:

  Contract Hash => Item
  def parse_search_item_to_item(beer)
    Item.new(original_name: beer.dig(:beer, :beer_name))
  end

The contract sometimes fails. I think it's because valid? is called on the resulting Item. Because valid? is an ActiveRecord class and there is a validator that doesn't pass the contract fails.

i.e. Item.valid? runs the ActiveRecord validators which return false in this case.

Seems like there is a naming collision here with valid?. Any suggestions?

nickpoorman avatar Oct 24 '16 21:10 nickpoorman

You can always use a Proc instead of a class as the contract when valid? is being used by the class for another purpose.

require 'contracts'

include Contracts::Core
C = Contracts

class Item
  def self.valid?(_x)
    false
  end
end

# This won't work since Item uses valid? for another purpose
Contract C::None => Item
def foo
  Item.new
end

begin
  foo
rescue => e
  puts e
end

# This works as desired
Contract C::None => ->(item){ item.is_a? Item }
def bar
  Item.new
end

bar

lj-ditrapani avatar Jan 08 '17 12:01 lj-ditrapani

Ouch. I don't have a great suggestion here, maybe I should have picked a different name...

egonSchiele avatar Jan 17 '17 22:01 egonSchiele