Search code examples
ruby-on-railsrubymongoiddelegation

Using record delegations with Mongoid Rails and Ruby


I am using ruby 2, rails 4, and mongoid-rails gem

I have two models:

class Product
  embeds_one :feature
end

class Feature
  embedded_in :product

  field :color, type: String
end

Lets say I have a product:

p = Product.new

I want to be able to call something like:

p.color = "blue"

instead of having to do:

p.feature.color = "blue"

the same goes for calling attributes:

p.color
=> "blue"

vs. the less ideal (and current situation)

p.feature.color
=> "blue"

I know with active records you can use delegations, but how would I set this up in mongoid without having to fill up my model with tons of methods referencing the feature model?


Solution

  • delegate method is not limited to Active record - it comes with Active Support and may be used on any class to delegate any method to any internal objects:

    require 'active_support/all'
    class A
      def initialize(a)
        @a = a
      end
      delegate :+, to: :@a
    end
    
    A.new(2) + 4     #=> 6
    

    Hence you can use it as well for your models. Just remember to add allow_nil: true so it doesn't throw an exception if it has no feature.

    class Product
      embeds_one :feature
    
      delegate :color, to: :feature, allow_nil: true
    end