← Back to Upcase

Design pattern advice: PORO collection scopes and relationships


(Chris O'Donnell) #1

Hey, I need advice with dealing with non-Active Record collections and making them available as a method on another object.
Note no ActiveRecord models are being used here.

I have a really simple class:
it holds on to an array of other models and that collection is given a name.

class MultiOptionPlan
  include ActiveModel::Model

  attr_accessor :plans, :name
end

What I want to do is pass this collection into another class and make it available as a method with its name.

class PlansTable
  include ActiveModel::Model

  attr_accessor :multi_option_plans, :plans
end

What I want:

table = PlansTable.new(multi_option_plans: MultiOptionPlan.new(plans: foo_plans, name: "foo"))
table.foo => foo_plans

I could do have MultiOptionPlan assign it self to its table via instance_eval, or I could override missing_method on the table class, to select the multi_option_plan with the desired name. Looking for best approach.


(Geoff Harcourt) #2

Is multi_option_plans a collection? If so, it seems like in your example you might need to wrap multi_option_plans: MultiOptionPlan.new(...) in an array.


(Chris O'Donnell) #3

Hey thanks for the reply.

what I have so far is

  class PlansTable
    include ActiveModel::Model

    attr_reader :multi_option_plans

      def multi_option_plans=(multi_plan)
        @multi_option_plans = {}
        name = multi_plan.name
        @multi_option_plans[name.to_sym] = multi_plan.plans
      end

Which this kinda works

table.multi_option_plans[:foo_plans]

but its probably better to hold a reference to the object. So I can call methods on the collection.

 def multi_option_plans=(multi_plan)
   @multi_option_plans = {}
   name = multi_plan.name
   @multi_option_plans[name.to_sym] = multi_plan
 end

thoughts?