Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I replicate class_inheritable_accessor's behavior in Rails 3.1?

Beginning with Rails 3.1, class_inheritable_accessor produces deprecation warnings, telling me to use class_attribute instead. But class_attribute behaves differently in an important way which I will demonstrate.

A typical use of class_inheritable_attribute would be a presenter class, like so:

module Presenter
  class Base
    class_inheritable_accessor :presented
    self.presented = {}

    def self.presents(*types)
      types_and_classes = types.extract_options!
      types.each {|t| types_and_classes[t] = t.to_s.tableize.classify.constantize }
      attr_accessor *types_and_classes.keys
      types_and_classes.keys.each do |t|
        presented[t] = types_and_classes[t]
      end
    end
  end
end

class PresenterTest < Presenter::Base
  presents :user, :person
end

Presenter::Base.presented => {}
PresenterTest.presented => {:user => User, :person => Person}

But using class_attribute, subclasses will pollute their parents:

Presenter::Base => {:user => User, :person => Person}

Which is not desired behavior at all. Is there another type of accessor that behaves the correct way, or do I need to switch to another pattern altogether? How should I replicate the same behavior without class_inheritable_accessor?

like image 785
Adam Lassek Avatar asked Jul 07 '11 22:07

Adam Lassek


1 Answers

class_attribute won't pollute its parent if it's used as intended. Make sure you're not changing the mutable items in-place.

types_and_classes.keys.each do |t|
  self.presented = presented.merge({t => types_and_classes[t]})
end
like image 117
bensie Avatar answered Sep 18 '22 20:09

bensie