Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #9694 (closed enhancement: untested)

Opened 9 months ago

Last modified 8 months ago

Remove abstract classes from STI find conditions

Reported by: mrj Assigned to: core
Priority: normal Milestone: 2.x
Component: ActiveRecord Version: edge
Severity: normal Keywords: sti abstract_class type_condition type
Cc: webmaster@joaz.de

Description

When the single-table inheritance type column is present, conditions are added to finds that restrict matched records to those that have a type field that is either the name of the class on which the find is run or the name of any class that inherits (arbitrarily deeply) from this class.

This patch excludes abstract classes (those marked self.abstract_class = true) from this disjunction of class name matches, speeding the database command.

Attachments

sti_conds_skip_abstract_classes.diff (1.1 kB) - added by mrj on 09/26/07 13:17:08.
Untested Patch
patched_9694_patch.diff (1.0 kB) - added by jglauche on 11/22/07 14:38:24.
fixed the previous patch
patched_9694_second_patch.diff (1.1 kB) - added by jglauche on 11/22/07 17:12:03.
fixed patch, please test!

Change History

09/26/07 13:17:08 changed by mrj

  • attachment sti_conds_skip_abstract_classes.diff added.

Untested Patch

11/22/07 14:38:24 changed by jglauche

  • attachment patched_9694_patch.diff added.

fixed the previous patch

11/22/07 14:40:01 changed by jglauche

  • cc set to webmaster@joaz.de.

11/22/07 15:15:42 changed by jglauche

err, my patch is still faulty.

This line doesnt work as expected: subclass.abstract_class? ? condition : condition << "#{table_name}.#{quoted_inheritance_column} = '#{subclass.name.demodulize}'"

so when subclass is not an abstract class it will add type='subclass' which is not what we want.

Here is an example why I need it: ( as posted here http://www.ruby-forum.com/topic/132559#591034 )

class SomeAbstractModel < ActiveRecord::Base

self.abstract_class = true

end

I've a table Foo with a column "type", since I've subclasses of Foo.

If this class is defined like this class Foo < ActiveRecord::Base end

a simple select produces this query: # Foo.find(1) SELECT * FROM foo WHERE (foo."id" = 1)

If I change the superclass of Foo to my Abstract Model: class Foo < SomeAbstractModel end

the simple select produces now a different query # Foo.find(1) SELECT * FROM foo WHERE (foo."id" = 1) AND ( (foo."type" = 'Foo' ) )

The problem is, for some reason, I've some rows where "type" is NULL and those are not found with it.

11/22/07 17:12:03 changed by jglauche

  • attachment patched_9694_second_patch.diff added.

fixed patch, please test!

11/22/07 17:13:12 changed by jglauche

  • status changed from new to closed.
  • resolution set to untested.

I've made a minor change to my patch, see second patch.

This one works for me. Please test!

11/22/07 18:12:55 changed by norbert

Usually the "untested" ticket resolution is used by others to indicate the creator of the patch should add unit tests. This is actually the case here (trust me, STI is quite brittle), so I will leave the ticket closed.

If you want to get a patch into Rails, read up on the wiki frontpage and get some people to "plus one" it. This will also get your ticket up on WWR.