Forum: Ruby on Rails belongs_to not working as expected

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
uberlordchris (Guest)
on 2009-04-24 21:28
(Received via mailing list)
I'm using ActiveRecord 2.3.2.  I have a class with a belongs_to
association like this:

  class Foo < ActiveRecord::Base
    belongs_to :bar
  end

It is valid for bar to be nil (thus, in the database, foos.bar_id can
be null).  However, if I execute the following I get an error:

  foo = Foo.new
  foo.bar # => nil
  foo.save!
  foo.bar # expect nil but get error

The full error message is, "ActiveRecord::RecordNotFound (Couldn't
find Bar without an ID)".  Tracing the code I see that
ActiveRecord::Base.find_from_ids(ids, options) is being called by
passing an array containing a single, nil, element for the ids
argument.  Here is the method:

  def find_from_ids(ids, options)
    expects_array = ids.first.kind_of?(Array)
    return ids.first if expects_array && ids.first.empty?

    ids = ids.flatten.compact.uniq

    case ids.size
      when 0
        raise RecordNotFound, "Couldn't find #{name} without an ID"
      when 1
        result = find_one(ids.first, options)
        expects_array ? [ result ] : result
      else
        find_some(ids, options)
    end
  end

Without delving further to assess other consequences, it seems to me
that either nil should be returned when ids.size == 0 or the line "ids
= ids.flatten.compact.uniq" should be replaced with:

  ids = ids.flatten.uniq
  return nil if ids.length == 1 && ids.first.nil?
  ids.compact!

Any thoughts gratefully received!

Thanks,

Chris.
Robert W. (Guest)
on 2009-04-24 23:06
uberlordchris wrote:
> I'm using ActiveRecord 2.3.2.  I have a class with a belongs_to
> association like this:
>
>   class Foo < ActiveRecord::Base
>     belongs_to :bar
>   end
>
> It is valid for bar to be nil (thus, in the database, foos.bar_id can
> be null).  However, if I execute the following I get an error:
>
>   foo = Foo.new
>   foo.bar # => nil
>   foo.save!
>   foo.bar # expect nil but get error

I just tried this myself with Rails 2.3.2 and it worked as expected so
I'm not sure what wrong.

What does your Foo table look like?

Mine is:

foos
------------
|id|bar_id|name|created_at|updated_at|
This topic is locked and can not be replied to.