← Back to Upcase

Problem with Adding Concern w/ Dynamic Attribute Accessors


(Kevin Lozandier) #1

After seeing repetition in my models involving ‘states’, I attempted to create a concern only to have problems being able to dynamically create virtual attributes with the models name.

Suppose I wanted to refactor the following tings inside a model to a concern:

class Project < ActiveRecord::Base 

attr_accessor :approve_project, :unapprove_project
  
  #special actions 
  before_save :perform_state_change

  
  # State Machine 
  state_machine :state, initial: :pending do 

    state :coming_soon 

    event :approve do 
      transition any => :approved 
    end

    event :not_approved do 
      transition any => :pending
    end
  end

  def perform_state_change 
    self.state = 'approved' if approve_project == '1' 
    self.state = 'pending' if unapprove_project == '1'
  end


end

I attempted the following with no luck

module WorkStates
  extend ActiveSupport::Concern 
  included do 
    # also tried .constantize with no luck; would try __send__ or  self.send(:attr_accessor, ) if I understood what would have to be passed in here
    attr_accessor "approve_#{self.to_s.downcase}".to_sym, "unapprove_#{self.to_s.downcase}".to_sym

    state_machine :state, initial: :pending do 

      state :coming_soon 

      event :approve do 
        transition any => :approved 
      end

      event :not_approved do 
        transition any => :pending
      end
    end
  end

  def perform_state_change 
    self.state = 'approved' if "approve_#{self.class.to_s.downcase}".constantize == 1 
    self.state = 'pending' if "unapprove_#{self.class.to_s.downcase}".constantize == 1
  end

end


When attempting to do the following I get invalid variable ':approve_project' errors.

Any idea on what I would have to refactor to get this concern to properlly work?