Skip to content
This repository has been archived by the owner on Apr 17, 2018. It is now read-only.

[PATCH] Discriminator type demodulize feature request #27

Open
solnic opened this issue May 17, 2011 · 5 comments
Open

[PATCH] Discriminator type demodulize feature request #27

solnic opened this issue May 17, 2011 · 5 comments

Comments

@solnic
Copy link
Contributor

solnic commented May 17, 2011

We all know Discriminator type, but what I wish it to support is some kind of demodulize functionality, let's say:

property :type, Discriminator, :demodulize => true

Normally Discriminator type generate this insert for the code presented in the footer:

INSERT INTO "very_long_module1_very_long_module2_as" ("type") VALUES ('VeryLongModule1::VeryLongModule2::A::A1')

with :demodulize => true options it would be:

INSERT INTO "very_long_module1_very_long_module2_as" ("type") VALUES ('A1')

When you use inheritance in the way I presented below (ie. nested classes), the module A will see and recognize A1 and A2 class, even if you don't prefixe them by "VeryLongModule1::VeryLongModule2::A". I know it could be a problem if you inherit from A class in different Object spaces, in this cases Discriminator needs full path to find them, but it depends on programmer to use it right.

require 'rubygems'
require 'dm-core'
require 'dm-types'

DataMapper::Logger.new(STDOUT, :debug)
DataMapper.setup(:default, 'sqlite3::memory:')

module VeryLongModule1
  module VeryLongModule2
    class A
      include DataMapper::Resource

      property :id, Serial
      property :type, Discriminator # :demodulize => true

      class A1 < self
      end

      class A2 < self
      end
    end

    DataMapper.auto_migrate!

    A::A1.new.save
  end
end

Here is a pull request for a path that will open possibility to create custom discriminator types
http://github.com/dmgr/dm-core/commit/58017d02987e9fdbae23750c3ab1079f47b3e5c5


Created by Dawid Marcin Grzesiak - 2010-03-27 09:00:06 UTC

Original Lighthouse ticket: http://datamapper.lighthouseapp.com/projects/20609/tickets/1226

@solnic
Copy link
Contributor Author

solnic commented May 17, 2011

The patch at http://github.com/dmgr/dm-core/commit/58017d02987e9fdbae23750c3ab1079f47b3e5c5 looks good as it will allow to implement your specific needs in dm-types which probably is a better place then dm-core, like you said on IRC.

by Martin Gamsjaeger (snusnu)

@solnic
Copy link
Contributor Author

solnic commented May 17, 2011

I created a repo with my custom discriminator types:
http://github.com/dmgr/dmg-types

In the future they can be moved to dm-types if core developers want it.

They will work if you will merge my commit, I prefer this one:
http://github.com/dmgr/dm-core/commit/6af8cab37dfeb7aa1b0230399fddf239e6aac590

by Dawid Marcin Grzesiak

@solnic
Copy link
Contributor Author

solnic commented May 17, 2011

The commit: http://github.com/dmgr/dm-core/commit/83fba6abcf8bdb2e41371c3d20e78a26950c54dc
will let you do something like this:

require &rsquo;rubygems&rsquo;
require &rsquo;datamapper&rsquo;

DataMapper.setup(:default, "sqlite3::memory:")

class Car
  include DataMapper::Resource

  property :id, Serial
  @brand = property :brand, String
  @name = property :name, String

  class Ford < self
    class Torino < self
    end
  end

  class Audi < self
    class TT < self
    end
  end

  def self.discrimination(record)
    case record[@brand]
      when "Audi" then if &rsquo;TT&rsquo; == record[@name]
          Audi::TT
        else
          Audi
        end
      when "Ford" then if &rsquo;Torino&rsquo; == record[@name]
          Ford::Torino
        else
          Ford
        end
      else self
    end
  end
end

p Car.new(:brand => &rsquo;Opel&rsquo;, :name => &rsquo;Astra&rsquo;)  #<Car @id=nil @brand="Opel" @name="Astra">
p Car.new(:brand => &rsquo;Ford&rsquo;, :name => &rsquo;K&rsquo;)      #<Car::Ford @id=nil @brand="Ford" @name="K">
p Car.new(:brand => &rsquo;Ford&rsquo;, :name => &rsquo;Torino&rsquo;) #<Car::Ford::Torino @id=nil @brand="Ford" @name="Torino">
p Car.new(:brand => &rsquo;Audi&rsquo;, :name => &rsquo;TT&rsquo;)     #<Car::Audi::TT @id=nil @brand="Audi" @name="TT">

Additionally default scopes need to be updated in derived classes.

by Dawid Marcin Grzesiak

@solnic
Copy link
Contributor Author

solnic commented May 17, 2011

Because I need this behavior in my project I had to implement it on v0.10.2 so the solution I use is there:
http://github.com/dmgr/dm-core/tree/my0.10.2

and the code for master branch which I provided before:
http://github.com/dmgr/dm-core
is not the actual one.

by Dawid Marcin Grzesiak

@solnic
Copy link
Contributor Author

solnic commented May 17, 2011

Yeah, I generally like to hold onto adding new features into the core until there is at least a few people asking for them. Even then I think new features should be put into plugins, and stabilized there. Once it gets enough usage we can talk about moving it into the core.

I would suggest packaging this up into a plugin, and then seeing if there is any interest on the DataMapper mailing list.

by Dan Kubb (dkubb)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant