jeremyevans / sequel

Sequel: The Database Toolkit for Ruby
http://sequel.jeremyevans.net
Other
4.99k stars 1.07k forks source link

find_or_create doesn't take conditional input #926

Closed britishtea closed 9 years ago

britishtea commented 9 years ago

Using find_or_create with a Sequel::SQL::BooleanExpression (and I suspect anything other than a Hash) raises an error.

class User < Sequel::Model(:users)
end

User.find_or_create Sequel.ilike(:nickname, "britishtea") do |u|
  u.nickname = nickname
end
$ ruby test.rb
/Users/jip/.gem/ruby/1.9.3/gems/sequel-4.18.0/lib/sequel/model/base.rb:2058:in `initialize_set': undefined method `empty?' for #<Sequel::SQL::BooleanExpression:0x007ffbfb090638> (NoMethodError)
    from /Users/jip/.gem/ruby/1.9.3/gems/sequel-4.18.0/lib/sequel/model/base.rb:1161:in `initialize'
    from /Users/jip/.gem/ruby/1.9.3/gems/sequel-4.18.0/lib/sequel/model/base.rb:148:in `new'
    from /Users/jip/.gem/ruby/1.9.3/gems/sequel-4.18.0/lib/sequel/model/base.rb:148:in `create'
    from /Users/jip/.gem/ruby/1.9.3/gems/sequel-4.18.0/lib/sequel/model/base.rb:332:in `find_or_create'
    from test.rb:8:in `<main>'

The workaround is easy enough, so I'm not sure if this should just be stated in the documentation or actually be fixed.

jeremyevans commented 9 years ago

This is expected. User.create(Sequel.ilike(:nickname, "britishtea")) doesn't make sense. The find_or_create rdoc states that it calls create with the argument if the find fails, and since create would fail with such an argument (since it only takes a hash), I think that implies it shouldn't work.

I can understand what you want, but the find_or_create API is not designed to handle that use case.