Topic: How to update scoped records.

Hi All,
I have a table of resource names that is made up of controller names and action names.

class ControllerAction < ActiveRecord::Base
  belongs_to :controller_names
  belongs_to :action_names
end
class ActionName < ActiveRecord::Base
  has_many :controller_actions
end
class ControllerName < ActiveRecord::Base
  has_many :controller_actions
end

All good so far. Next I added a roles table and an interractions table to form a mtm between Role and ControllerName.

class Role < ActiveRecord::Base
  has_many :interactions, :dependent => :destroy
  has_many :controller_actions, :through => :interactions
end
class Interaction < ActiveRecord::Base
  belongs_to :controller_action
  belongs_to :role
end

class ControllerAction < ActiveRecord::Base
  belongs_to :controller_names
  belongs_to :action_names

  has_many :interactions, :dependent => :destroy
  has_many :roles, :through => :interactions
end
class ActionName < ActiveRecord::Base
  has_many :controller_actions
end
class ControllerName < ActiveRecord::Base
  has_many :controller_actions
end

Again all ok so far, I can edit the Roles associated with individual ControllerNames with the controller_names_controller.

But how can I edit all the ControllerNames Roles with a particular ActionName with the action_name_controller or, coversely edit all the ControllerNames Roles with a particular ControllerName with the controller_name_controller.

I can view the records but the PUT fails with:-

Cannot modify association 'ActionName#interactions' because the source reflection class 'Interaction' is associated to 'ControllerAction' via :has_many.

My models are:-

class Role < ActiveRecord::Base
  has_many :interactions, :dependent => :destroy
  has_many :controller_actions, :through => :interactions
  attr_accessible :name
end
class Interaction < ActiveRecord::Base
  belongs_to :controller_action
  belongs_to :role
  attr_accessor :enable # nice little thingy here
  attr_accessible :enable, :controller_action_id, :role_id
end
class ControllerName < ActiveRecord::Base
  has_many :controller_actions

  attr_accessor :enable # nice little thingy here
  attr_accessible :enable
  attr_accessible :name
end

class ActionName < ActiveRecord::Base
  attr_accessor :enable # nice little thingy here
  attr_accessible :enable
  attr_accessible :name, :controller_actions_attributes, :interactions_attributes #, :roles_attributes,
  attr_accessible :action_name_id, :controller_name_id

  has_many :controller_actions
  has_many :interactions, :through => :controller_actions
  has_many :roles, :through => :interactions

  accepts_nested_attributes_for :controller_actions, :interactions, :roles, :allow_destroy => true
end
class ControllerAction < ActiveRecord::Base
  belongs_to :controller_names
  belongs_to :action_names
  has_many :interactions, :dependent => :destroy
  has_many :roles, :through => :interactions
  accepts_nested_attributes_for :controller_names, :action_names, :roles, :interactions
  attr_accessible :name, :controller_name_id, :action_name_id, :role_id, :interactions_attributes

  scope :controllers, lambda {|name| where("controller_name_id = ?", name)}
  scope :actions, lambda {|name| where("action_name_id = ?", name)}

  def initialized_interactions() # this is the key method
    [].tap do |o|
      Role.all.each do |r|
        if p = interactions.find { |p| p.role_id == r.id }
          o << p.tap { |p| p.enable ||= true }
        else
          o << Interaction.new(:role_id => r.id)
        end
      end
    end
  end
end

Any suggestions ?

Last edited by ozzy (2013-03-12 09:55:06)