Gabriel Sobrinho
2013-Feb-18 12:55 UTC
Change behavior of `ActiveRecord::Base.new == ActiveRecord::Base.new`
Hi everyone, The active record documentation says the following: Note that new records are different from any other record by definition, unless the other record is the receiver itself. Besides, if you fetch existing records with select and leave the ID out, you’re on your own, this predicate will return false. But that''s really strange for me: User.new == User.new => false Since other data objects usually returns true if the containing data is equal: String.new == String.new => true OpenStruct.new == OpenStruct.new => true Take a look on this code: u1 = User.first u1.name = ''John Doe'' u2 = User.first u2.name = ''John Smith'' u1 == u2 => true The ActiveRecord::Base#== only compares the class and the id: def ==(comparison_object) super || comparison_object.instance_of?(self.class) && id.present? && comparison_object.id == id end The method may be changed to compare the class and the attributes: def ==(comparison_object) super || comparison_object.instance_of?(self.class) && comparison_object.attributes == attributes end The latter will behave like other data objects on ruby. I can overwrite this method only on my application or my model or even compare manually like this: User.new.attributes == User.new.attributes Regardless of that, the current behavior seems wrong. There is a specific reason to the active record behavior be implemented in this way? -- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Maurício Linhares
2013-Feb-18 13:05 UTC
Re: Change behavior of `ActiveRecord::Base.new == ActiveRecord::Base.new`
ActiveRecord defines identity using the DB primary key and class, if there isn''t a primary key it defaults to Ruby''s object identity which is if it is exactly the same object in memory. String and OpenStruct have their own definitions of what object equality means (both are based on content) so I don''t think it relates in any way to ActiveRecord, since it uses it''s own definition of what being == means. - Maurício Linhares http://techbot.me/ - http://twitter.com/#!/mauriciojr On Mon, Feb 18, 2013 at 9:55 AM, Gabriel Sobrinho <gabriel.sobrinho@gmail.com> wrote:> Hi everyone, > > The active record documentation says the following: > > Note that new records are different from any other record by definition, > unless the other record is the receiver itself. Besides, if you fetch > existing records with select and leave the ID out, you’re on your own, this > predicate will return false. > > > But that''s really strange for me: > > User.new == User.new > => false > > > Since other data objects usually returns true if the containing data is > equal: > > String.new == String.new > => true > > OpenStruct.new == OpenStruct.new > => true > > > Take a look on this code: > > u1 = User.first > u1.name = ''John Doe'' > > u2 = User.first > u2.name = ''John Smith'' > > u1 == u2 > => true > > > The ActiveRecord::Base#== only compares the class and the id: > > def ==(comparison_object) > super || > comparison_object.instance_of?(self.class) && > id.present? && > comparison_object.id == id > end > > > The method may be changed to compare the class and the attributes: > > def ==(comparison_object) > super || > comparison_object.instance_of?(self.class) && > comparison_object.attributes == attributes > end > > > The latter will behave like other data objects on ruby. > > I can overwrite this method only on my application or my model or even > compare manually like this: > > User.new.attributes == User.new.attributes > > > Regardless of that, the current behavior seems wrong. > > There is a specific reason to the active record behavior be implemented in > this way? > > -- > You received this message because you are subscribed to the Google Groups > "Ruby on Rails: Core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to rubyonrails-core+unsubscribe@googlegroups.com. > To post to this group, send email to rubyonrails-core@googlegroups.com. > Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. > For more options, visit https://groups.google.com/groups/opt_out. > >-- You received this message because you are subscribed to the Google Groups "Ruby on Rails: Core" group. To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-core+unsubscribe@googlegroups.com. To post to this group, send email to rubyonrails-core@googlegroups.com. Visit this group at http://groups.google.com/group/rubyonrails-core?hl=en. For more options, visit https://groups.google.com/groups/opt_out.