model inheritance and index

160 views
Skip to first unread message

Hung Tran

unread,
Sep 27, 2012, 7:55:03 PM9/27/12
to ohm-...@googlegroups.com
I have a base model which subclasses Ohm::Model, my other models would subclass this submodel. In addition in my submodel i have an attribute common to all other models that I furthermore want to have in index created on this attribute. This would allow me to have a consistent way for all models to be found by this property.

HOWEVER, this does not seem to be working as Ohm just skips creating the necessary index, unless I define the index inside of the child class but referring to the inherited property. this works but does not appear elegant as all of my child classes would have to have this declaration. See below:

# base model note i'm using ohm/contrib plugins in the base class and so all of my derived classes thus further making this design more beneficial/efficient
class BaseModel < Ohm::Model
  include Ohm::Timestamps
  include Ohm::DataTypes
  include Ohm::Callbacks

  attribute :uid

  index      :uid

  def before_create
    self.uid = SecureRandom.uuid
  end
end

# child 1
class Person < BaseModel
  attribute     :name
end

# child 2
class Post < BaseModel
  attribute   :title
end  

#usage
person = Person.create(name: "Salvatore Sanfillipo")
post = Post.create(title: "On cryptography and dogmas")

# blows up! with exeption:
Person.find(:uid => "c842563d-2f03-470b-91fd-379e668a9b8f") 
# =>  Ohm::IndexNotFound: Ohm::IndexNotFound

# Work around
class Person < BaseModel
    attribute :name
    index  :uid
end
class Post < BaseModel
    attribute :title
    index   :uid
end 


# With this work around the index is created.
# Note: be sure to flush your keys and delete models created.
  person = Person.create(name: "Salvatore Sanfillipo")
  post = Post.create(title: "On cryptography and dogmas")

  Person.find(uid: "created-uid").size > 0
  Place.find(uid: "created-uid-place").size >0


Hung Tran

unread,
Sep 28, 2012, 9:12:33 AM9/28/12
to ohm-...@googlegroups.com
I left out in my example above - that i would want to do the same with unique.


class BaseModel < Ohm::Model
  include Ohm::Timestamps
  include Ohm::DataTypes
  include Ohm::Callbacks

  attribute :uid

       unique            :uid

tribalvibes

unread,
Sep 28, 2012, 4:57:49 PM9/28/12
to ohm-...@googlegroups.com
Tran, these are exactly the requirements we solved a year ago with the 0.3 fork which we are using in a production application. Check out https://github.com/tribalvibes/ohm  and if you scroll all the way down the readme there is tutorial documentation for polymorphism, serialized attributes, union finds, etc.

Soveran's fork has diverged and seems they are making a lot of questionable breaking changes of late without much community input. Some of the features of 1.0 have been rolled into 0.3 such as pipelined fetch for performance whereas others such as unique indices are still on our 'todo' list but are easier to work around than the total lack of polymorphism support in the core in 1.0.

Feel free to merge the unique index feature from 1.0 and send a pull request. They've done a lot of work with MultiSet etc. so those pieces are no longer directly source compatible but uniques should be pretty easy to backport.

Happy to answer any questions.

Cheers,
.tv/

Michel Martens

unread,
Sep 29, 2012, 4:17:23 PM9/29/12
to ohm-...@googlegroups.com
Hey,

On Thu, Sep 27, 2012 at 8:55 PM, Hung Tran <htran...@gmail.com>
wrote:
> I have a base model which subclasses Ohm::Model, my other models
> would subclass this submodel. In addition in my submodel i have an
> attribute common to all other models that I furthermore want to have
> in index created on this attribute. This would allow me to have a
> consistent way for all models to be found by this property.
>
> HOWEVER, this does not seem to be working as Ohm just skips creating
> the necessary index, unless I define the index inside of the child
> class but referring to the inherited property. this works but does
> not appear elegant as all of my child classes would have to have
> this declaration. See below:

This is a known issue, it's documented at
https://github.com/soveran/ohm/pull/30.

The reason why we don't deal with inheritance is because the cost of
avoiding it in our applications is smaller than the cost of adding
complexity to the library implementation.

You can either use tribalvibes' fork, which includes that feature, or
avoid the problem and use composition instead, or just extract the
functionality to modules.
Reply all
Reply to author
Forward
0 new messages