FAQ
What I would like to accomplish is idea to have basic module which could be
later extended by anyone. But to retain same collection name. For example
basic user functionality provides username and title. Some other user would
like to extend model by adding signature and picture, third user would add
something else.

class User
include Mongoid::Document

field :username, type: String
field :title, type: String
end

1. solution
class Myuser < User
:signature, type: String
:picture, type: String
end

Is not ok since we get new class and therefor new collection name.

2. solution. Monkeypatching is not working either. At least not what I was
trying.

Any other suggestions?

by
TheR

Search Discussions

  • Arthur Neves at Jan 2, 2013 at 8:41 pm
    I would do something like this:


    module BasicUser
    extend ActiveSupport::Concern

    included do
    field :username, type: String

    field :title, type: String
    end
    end

    class User
    include Mongoid::Document
    include BasicUser

    field :signature, type: String
    end

    So you have a BasicUser module, and class User can include it.

    --
    Arthur Nogueira Neves
    @arthurnn

    On Wednesday, 2 January, 2013 at 3:04 PM, TheR wrote:

    What I would like to accomplish is idea to have basic module which could be later extended by anyone. But to retain same collection name. For example basic user functionality provides username and title. Some other user would like to extend model by adding signature and picture, third user would add something else.

    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    end

    1. solution
    class Myuser < User
    :signature, type: String
    :picture, type: String
    end

    Is not ok since we get new class and therefor new collection name.

    2. solution. Monkeypatching is not working either. At least not what I was trying.

    Any other suggestions?

    by
    TheR

  • James Stewart at Jan 2, 2013 at 10:16 pm

    On 2 Jan 2013, at 20:04, TheR wrote:
    What I would like to accomplish is idea to have basic module which could be later extended by anyone. But to retain same collection name. For example basic user functionality provides username and title. Some other user would like to extend model by adding signature and picture, third user would add something else.

    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    end

    1. solution
    class Myuser < User
    :signature, type: String
    :picture, type: String
    end

    Is not ok since we get new class and therefor new collection name.
    Does store_in do what you want? http://mongoid.org/en/mongoid/docs/documents.html#storage

    That way you'd have:

    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    end

    class Myuser < User
    store_in collection: 'myusers'

    field :signature, type: String
    field :picture, type: String
    end

    I've not used this myself but it looks like it would work.

    James.
  • Tal Atlas at Jan 3, 2013 at 4:41 am
    Your first solution will work just fine. Model inheritance works by putting
    them all in the same collection.

    Try out the code you have in solution 1, it'll work.
    On Wednesday, January 2, 2013 3:04:09 PM UTC-5, TheR wrote:

    What I would like to accomplish is idea to have basic module which could
    be later extended by anyone. But to retain same collection name. For
    example basic user functionality provides username and title. Some other
    user would like to extend model by adding signature and picture, third user
    would add something else.

    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    end

    1. solution
    class Myuser < User
    :signature, type: String
    :picture, type: String
    end

    Is not ok since we get new class and therefor new collection name.

    2. solution. Monkeypatching is not working either. At least not what I was
    trying.

    Any other suggestions?

    by
    TheR


  • TheR at Jan 3, 2013 at 6:55 am
    Thanks to all. But it is not quite what I want. Maybe I didn't specified it
    good enough. All your cases are good for single inheritance. But what if n
    people would like to contribute to a model. They would all have to be
    synnchronized.

    Example:
    Class User1 < User
    end
    Class User2 < User1
    end
    Class UserN < UserN_1
    end

    What is not particular practical in praxis.

    In big applications you often get cases where tables are extended by adding
    another table to database and linked by id to main table.
    Simple example:
    Class User
    end
    Class User1
    field: user_id
    end
    Class UserN
    field: user_id
    end
    If you have list of all extensions, you can treat all tables as single
    table. But in Mongo this can be much simpler, since it can be accomplished
    in single record (document). The problem is just how to describe it with
    Mongoid models.

    by
    TheR
  • Durran Jordan at Jan 3, 2013 at 9:23 am
    I'm not sure what you mean by your statement in #1: "Is not ok since we get
    new class and therefor new collection name. "

    This is not true. When using inheritance, Mongoid stores all the documents
    in the same collection, in your case "users". What would happen in your
    case is that classes of type User would get stored in the "users"
    collection with an additional field: "_type" => "User". MyUser documents
    would have a "_type" => "MyUser" stored with it along with the additional
    fields. Isn't this exactly what you want?

    2013/1/2 TheR <[email protected]>
    What I would like to accomplish is idea to have basic module which could
    be later extended by anyone. But to retain same collection name. For
    example basic user functionality provides username and title. Some other
    user would like to extend model by adding signature and picture, third user
    would add something else.

    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    end

    1. solution
    class Myuser < User
    :signature, type: String
    :picture, type: String
    end

    Is not ok since we get new class and therefor new collection name.

    2. solution. Monkeypatching is not working either. At least not what I was
    trying.

    Any other suggestions?

    by
    TheR


  • TheR at Jan 3, 2013 at 10:13 am
    I'm not sure what you mean by your statement in #1: "Is not ok since we
    get new class and therefor new collection name. "

    In this case you are correct. This is how mongoid behaves.
    This is not true. When using inheritance, Mongoid stores all the
    documents in the same collection, in your case "users". What would happen
    in your case is that classes of type User would get stored in the "users"
    collection with an additional field: "_type" => "User". MyUser documents
    would have a "_type" => "MyUser" stored with it along with the additional
    fields. Isn't this exactly what you want?

    No. That would mean a new document for every model definition. What I would
    like is that all fields from all definitions are saved to one document.


    by
    TheR


    Dne četrtek, 03. januar 2013 10:23:05 UTC+1 je oseba Durran Jordan napisala:
    I'm not sure what you mean by your statement in #1: "Is not ok since we
    get new class and therefor new collection name. "

    This is not true. When using inheritance, Mongoid stores all the documents
    in the same collection, in your case "users". What would happen in your
    case is that classes of type User would get stored in the "users"
    collection with an additional field: "_type" => "User". MyUser documents
    would have a "_type" => "MyUser" stored with it along with the additional
    fields. Isn't this exactly what you want?

    by
    TheR


  • Durran Jordan at Jan 3, 2013 at 10:43 am
    Can you just post a gist of how you want the single document stored in the
    database (the raw json or hash)? I think that would be easier to show you
    how to model it.

    2013/1/3 TheR <[email protected]>
    I'm not sure what you mean by your statement in #1: "Is not ok since we
    get new class and therefor new collection name. "

    In this case you are correct. This is how mongoid behaves.
    This is not true. When using inheritance, Mongoid stores all the
    documents in the same collection, in your case "users". What would happen
    in your case is that classes of type User would get stored in the "users"
    collection with an additional field: "_type" => "User". MyUser documents
    would have a "_type" => "MyUser" stored with it along with the additional
    fields. Isn't this exactly what you want?

    No. That would mean a new document for every model definition. What I
    would like is that all fields from all definitions are saved to one
    document.


    by
    TheR


    Dne četrtek, 03. januar 2013 10:23:05 UTC+1 je oseba Durran Jordan
    napisala:
    I'm not sure what you mean by your statement in #1: "Is not ok since we
    get new class and therefor new collection name. "

    This is not true. When using inheritance, Mongoid stores all the
    documents in the same collection, in your case "users". What would happen
    in your case is that classes of type User would get stored in the "users"
    collection with an additional field: "_type" => "User". MyUser documents
    would have a "_type" => "MyUser" stored with it along with the additional
    fields. Isn't this exactly what you want?

    by
    TheR


  • TheR at Jan 3, 2013 at 11:03 am
    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    end

    class MyUserExtension
    extends_model :user # just my imagination

    field :signature, type: String
    field :picture, type: String
    end

    Would be stored to document as if I did only single declaration.

    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    field :signature, type: String
    field :picture, type: String
    end

    I hope this is clear enough.

    by
    TheR


    Dne četrtek, 03. januar 2013 11:36:10 UTC+1 je oseba Durran Jordan napisala:
    Can you just post a gist of how you want the single document stored in the
    database (the raw json or hash)? I think that would be easier to show you
    how to model it.


  • Arthur Neves at Jan 3, 2013 at 2:32 pm
    Have u tried the solution i proposed . I guess it doest exaclty what u want.. Using include and concerns...

    --
    Arthur Neves

    On Thursday, 3 January, 2013 at 6:03 AM, TheR wrote:


    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    end

    class MyUserExtension
    extends_model :user # just my imagination

    field :signature, type: String
    field :picture, type: String
    end

    Would be stored to document as if I did only single declaration.

    class User
    include Mongoid::Document

    field :username, type: String
    field :title, type: String
    field :signature, type: String
    field :picture, type: String
    end

    I hope this is clear enough.

    by
    TheR


    Dne četrtek, 03. januar 2013 11:36:10 UTC+1 je oseba Durran Jordan napisala:
    Can you just post a gist of how you want the single document stored in the database (the raw json or hash)? I think that would be easier to show you how to model it.

  • TheR at Jan 3, 2013 at 8:01 pm
    For extending single class.

    Now imagine. You have working application and you would like to add
    additional functionality. You provide that with a gem. You would like to
    use existing user database, but need to add field to each document.

    With AR, you would make a migration and field would be added to table
    definition. But with mongoid all fields are defined inside model class. So
    how to extend this model class.

    by
    TheR


    Dne četrtek, 03. januar 2013 15:25:56 UTC+1 je oseba Arthur Neves napisala:
    Have u tried the solution i proposed . I guess it doest exaclty what u
    want.. Using include and concerns...

    --
    Arthur Neves


  • TheR at Jan 5, 2013 at 10:43 pm
    I decide to poke around source and I come out with this solution.

    User::field :signature, type: String
    User::belongs_to :visit
    User::embeds_many :roles

    Maybe just a little suggestion from my side, to make it little less ugly.

    User::extend do
    field :signature, type: String
    belongs_to :visit
    embeds_many :roles
    end

    by
    TheR
  • Daniel Doubrovkine at Jan 6, 2013 at 2:42 am
    A slightly cleaner approach is to put these in a module and then extend
    User with the module.

    module UserThing
    field ...
    end

    User.extend UserThing
    On Sat, Jan 5, 2013 at 5:43 PM, TheR wrote:


    I decide to poke around source and I come out with this solution.

    User::field :signature, type: String
    User::belongs_to :visit
    User::embeds_many :roles

    Maybe just a little suggestion from my side, to make it little less ugly.

    User::extend do
    field :signature, type: String
    belongs_to :visit
    embeds_many :roles
    end

    by
    TheR

    --

    dB. | Moscow - Geneva - Seattle - New York
    dblock.org <http://www.dblock.org> -
    @dblockdotorg<http://twitter.com/#!/dblockdotorg>
  • Arthur Neves at Jan 6, 2013 at 2:43 am
    my first email in this thread shows the module solution ....
    On Saturday, January 5, 2013, Daniel Doubrovkine wrote:

    A slightly cleaner approach is to put these in a module and then extend
    User with the module.

    module UserThing
    field ...
    end

    User.extend UserThing

    On Sat, Jan 5, 2013 at 5:43 PM, TheR ({}, 'cvml', '[email protected]');>
    wrote:
    I decide to poke around source and I come out with this solution.

    User::field :signature, type: String
    User::belongs_to :visit
    User::embeds_many :roles

    Maybe just a little suggestion from my side, to make it little less ugly.

    User::extend do
    field :signature, type: String
    belongs_to :visit
    embeds_many :roles
    end

    by
    TheR

    --

    dB. | Moscow - Geneva - Seattle - New York
    dblock.org <http://www.dblock.org> - @dblockdotorg<http://twitter.com/#!/dblockdotorg>

    --
    Arthur Nogueira Neves
    Follow me @arthurnn <http://www.twitter.com/arthurnn89>
  • Daniel Doubrovkine at Jan 6, 2013 at 2:59 am
    Indeed.

    I think for a non-experienced Rubyist it's unusual to open up a class
    post-definition, much less to pogrammatically extend it from another gem -
    which is where the whole confusion came from. Your example, while
    absolutely correct, didn't seem to answer TheR's question, it just needed
    to say `User.extend BasicUser`.

    I would use ActiveSupport::Concern as you suggest, too, just to keep things
    more structurally organized.
    On Sat, Jan 5, 2013 at 9:43 PM, Arthur Neves wrote:

    my first email in this thread shows the module solution ....

    On Saturday, January 5, 2013, Daniel Doubrovkine wrote:

    A slightly cleaner approach is to put these in a module and then extend
    User with the module.

    module UserThing
    field ...
    end

    User.extend UserThing
    On Sat, Jan 5, 2013 at 5:43 PM, TheR wrote:


    I decide to poke around source and I come out with this solution.

    User::field :signature, type: String
    User::belongs_to :visit
    User::embeds_many :roles

    Maybe just a little suggestion from my side, to make it little less ugly.

    User::extend do
    field :signature, type: String
    belongs_to :visit
    embeds_many :roles
    end

    by
    TheR

    --

    dB. | Moscow - Geneva - Seattle - New York
    dblock.org <http://www.dblock.org> - @dblockdotorg<http://twitter.com/#!/dblockdotorg>

    --
    Arthur Nogueira Neves
    Follow me @arthurnn <http://www.twitter.com/arthurnn89>


    --

    dB. | Moscow - Geneva - Seattle - New York
    dblock.org <http://www.dblock.org> -
    @dblockdotorg<http://twitter.com/#!/dblockdotorg>
  • TheR at Jan 6, 2013 at 1:15 pm
    my first emI think for a non-experienced Rubyist it's unusual to open up
    a class post-definition, much less to pogrammatically extend it from
    another gem - which is where the whole confusion came from. Your example,
    while absolutely correct, didn't seem to answer TheR's question, it just
    needed to say `User.extend BasicUser`.ail in this thread shows the module
    solution ....

    But it doesn't solve chicken egg problem ;-) In your example you define
    extension class before it has to be included in basic class.

    I wanted basic class to be fully defined and then extended sometime in
    future without touching source code.
    I think for a non-experienced Rubyist it's unusual to open up a class
    post-definition, much less to pogrammatically extend it from another gem -
    which is where the whole confusion came from. Your example, while
    absolutely correct, didn't seem to answer TheR's question, it just needed
    to say `User.extend BasicUser`.

    And now comes funny part. I didn't even know that extend exists in ruby
    syntax and that it almost just does what I wanted. What I have written was
    just a humble suggestion. Problem is in details. Extend can only extend
    module not class. So this example throws error: wrong argument type Class
    (expected Module)

    class UserForForum # or module
    extend User

    field :signature, type: String
    belongs_to :visit
    embeds_many :roles
    end


    Can you please make a suggestion.

    by
    TheR
  • TheR at Jan 6, 2013 at 1:19 pm
    my first email in this thread shows the module solution ....
    But it doesn't solve chicken egg problem ;-) In your example you define
    extension class before it has to be included in basic class.

    I wanted basic class to be fully defined and then extended sometime in
    future without touching source code.


    I think for a non-experienced Rubyist it's unusual to open up a class
    post-definition, much less to pogrammatically extend it from another gem -
    which is where the whole confusion came from. Your example, while
    absolutely correct, didn't seem to answer TheR's question, it just needed
    to say `User.extend BasicUser`.

    And now comes funny part. I didn't even know that extend exists in ruby
    syntax and that it almost just does what I wanted. What I have written was
    just a humble suggestion. Problem is in details. Extend can only extend
    module not class. So this example throws error: wrong argument type Class
    (expected Module)

    class UserForForum # or module
    extend User

    field :signature, type: String
    belongs_to :visit
    embeds_many :roles
    end


    Can you please make a suggestion.

    by
    TheR

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupmongoid @
categoriesmongodb, rubyonrails
postedJan 2, '13 at 8:04p
activeJan 6, '13 at 1:19p
posts17
users6
websitemongoid.org
irc#mongoid

People

Translate

site design / logo © 2023 Grokbase