I am experiencing strange problems with a HABTM relationship in my
application.
The two models concerned are Role and RoleType. When attempting to set
the RoleTypes on a Role within my controllers I receive an error with
the attached stack trace (see bottom).
Unfortunately I am unable to reproduce this error with a unit test, or
a functional test. I’ve even tried creating a new project to test the
exact bit of code, and still had no success reproducing the error.
I’ve also checked out the code on another computer and run up against
the same problems. This leads me to believe that the problem lies
somewhere I haven’t considered (i.e. outside the models /
controllers / migrations etc).
I’m basically looking for any pointers anyone might be able to offer
me. I’ve spent two and a half days (and counting) banging my head
against the wall on this one. I’m aware that this problem appears
similar to the below link but since there is no response to that
thread, and since the stack trace is quite different I thought I’d try
a post of my own.
I’ve simplified the code to attempt to isolate the issue; the specific
bit of code I’m trying to run is:
role = Role.find(1)
role_type = RoleType.find(1)
role.role_types = [role_type]
The exception is raised on the last line as I try to assign the list
of RoleTypes to the Role.
I’m running Lighttpd under XP with Rails 1.1.6 and Ruby 1.8.5
Thanks in advance for any assistance!
Hugh
My Role model:
class Role < ActiveRecord::Base
has_and_belongs_to_many :role_types
has_and_belongs_to_many :users
has_many :permissions
ROLE_TYPE_REVIEWER = ‘reviewer’
ROLE_TYPE_CONCLUSION_REVIEWER = ‘conclusion_reviewer’
ROLE_TYPE_COMMUNITY_REVIEWER = ‘community_reviewer’
ROLE_TYPE_INTEREST_TAG_REVIEWER = ‘interest_tag_reviewer’
ROLE_TYPE_BATCH_ADMINISTRATOR = ‘batch_administrator’
ROLE_TYPE_USER_ADMINISTRATOR = ‘user_administrator’
ROLE_TYPE_USER_GROUP_ADMINISTRATOR = ‘user_group_administrator’
ROLE_TYPE_CITIZEN_ADMINISTRATOR = ‘citizen_administrator’
ROLE_TYPE_INTEREST_TAG_ADMINISTRATOR = ‘interest_tag_administrator’
ROLE_TYPE_COMMUNITY_ADMINISTRATOR = ‘community_administrator’
ROLE_TYPE_ROLES_ADMINISTRATOR = ‘role_administrator’
ROLE_TYPE_QUESTIONS_ADMINISTRATOR = ‘question_administrator’
ROLE_TYPE_INTEREST_TAG_PROPOSER = ‘interest_tag_proposer’
ROLE_TYPE_COMMUNITY_PROPOSER = ‘community_proposer’
ROLE_TYPE_QUESTIONS_PROPOSER = ‘question_proposer’
ROLE_TYPES = {
ROLE_TYPE_REVIEWER => ‘Reviewer’,
ROLE_TYPE_CONCLUSION_REVIEWER => ‘Conclusion Reviewer’,
ROLE_TYPE_COMMUNITY_REVIEWER => ‘Community Reviewer’,
ROLE_TYPE_INTEREST_TAG_REVIEWER => ‘Interest Tag Reviewer’,
ROLE_TYPE_BATCH_ADMINISTRATOR => ‘Batch Administrator’,
ROLE_TYPE_USER_ADMINISTRATOR => ‘User Administrator’,
ROLE_TYPE_USER_GROUP_ADMINISTRATOR => ‘User Group Administrator’,
ROLE_TYPE_CITIZEN_ADMINISTRATOR => ‘Citizen Administrator’,
ROLE_TYPE_INTEREST_TAG_ADMINISTRATOR => ‘Interest Tag
Administrator’,
ROLE_TYPE_COMMUNITY_ADMINISTRATOR => ‘Community Administrator’,
ROLE_TYPE_ROLES_ADMINISTRATOR => ‘Role Administrator’,
ROLE_TYPE_QUESTIONS_ADMINISTRATOR => ‘Question Administrator’,
ROLE_TYPE_INTEREST_TAG_PROPOSER => ‘Interest Tag Proposer’,
ROLE_TYPE_COMMUNITY_PROPOSER => ‘Community Proposer’,
ROLE_TYPE_QUESTIONS_PROPOSER => ‘Question Proposer’
}
ROLE_NAMES = [
ROLE_TYPE_REVIEWER,
ROLE_TYPE_CONCLUSION_REVIEWER,
ROLE_TYPE_COMMUNITY_REVIEWER,
ROLE_TYPE_INTEREST_TAG_REVIEWER,
ROLE_TYPE_BATCH_ADMINISTRATOR,
ROLE_TYPE_USER_ADMINISTRATOR,
ROLE_TYPE_USER_GROUP_ADMINISTRATOR,
ROLE_TYPE_CITIZEN_ADMINISTRATOR,
ROLE_TYPE_INTEREST_TAG_ADMINISTRATOR,
ROLE_TYPE_COMMUNITY_ADMINISTRATOR,
ROLE_TYPE_ROLES_ADMINISTRATOR,
ROLE_TYPE_QUESTIONS_ADMINISTRATOR,
ROLE_TYPE_INTEREST_TAG_PROPOSER,
ROLE_TYPE_COMMUNITY_PROPOSER,
ROLE_TYPE_QUESTIONS_PROPOSER
]
CONTROLLERS = {
:batches => BatchesController.public_instance_methods(false),
:citizens => CitizensController.public_instance_methods(false),
:communities =>
CommunitiesController.public_instance_methods(false),
:interest_tags =>
InterestTagsController.public_instance_methods(false),
:login => LoginController.public_instance_methods(false),
:questions => QuestionsController.public_instance_methods(false),
:roles => RolesController.public_instance_methods(false),
:user_groups =>
UserGroupsController.public_instance_methods(false),
:users => UsersController.public_instance_methods(false),
:welcome => WelcomeController.public_instance_methods(false)
}
def alter_permissions(values)
result = self
if values
# delete all current permissions and create new ones
self.permissions.each { |permission|
permission.destroy
}
values.each {|value|
value_split = value.split(‘-’)
self.permissions << Permission.new(:controller =>
value_split[0], :page_action => value_split[1])
}
result = self.save!
end
return result
end
end
My Role migration:
class CreateRoles < ActiveRecord::Migration
def self.up
create_table :roles do |t|
t.column :name, :string
t.column :restricted, :boolean, :null => false, :default =>
false
end
Role.create(:name => ‘Role 1’)
end
def self.down
drop_table :roles
end
end
My RoleType model:
class RoleType < ActiveRecord::Base
has_and_belongs_to_many :roles
end
My RoleType migration:
class CreateRoleTypes < ActiveRecord::Migration
def self.up
create_table :role_types do |t|
t.column :name, :string
end
RoleType.create(:name => ‘Role 1’)
end
def self.down
drop_table :role_types
end
end
The exception’s stack trace:
ActiveRecord::AssociationTypeMismatch (RoleType expected, got
RoleType):
h:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.1/lib/
active_record/associations/association_proxy.rb:148:in
raise_on_type_mismatch' h:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.1/lib/ active_record/associations/association_collection.rb:137:in
replace’
h:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.1/lib/
active_record/associations/association_collection.rb:137:in each' h:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.1/lib/ active_record/associations/association_collection.rb:137:in
replace’
h:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.1/lib/
active_record/associations.rb:944:in role_types=' h:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.1/lib/ active_record/associations.rb:954:in
send’
h:/ruby/lib/ruby/gems/1.8/gems/activerecord-1.15.1/lib/
active_record/associations.rb:954:in role_type_ids=' /app/controllers/roles_controller.rb:50:in
update’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/base.rb:1095:in send' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/base.rb:1095:in
perform_action_without_filters’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/filters.rb:632:in call_filter' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/filters.rb:638:in
call_filter’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/filters.rb:438:in call' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/filters.rb:637:in
call_filter’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/filters.rb:638:in call_filter' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/filters.rb:438:in
call’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/filters.rb:637:in call_filter' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/filters.rb:638:in
call_filter’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/filters.rb:438:in call' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/filters.rb:637:in
call_filter’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/filters.rb:619:in perform_action_without_benchmark' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/benchmarking.rb:66:in
perform_action_without_rescue’
h:/ruby/lib/ruby/1.8/benchmark.rb:293:in measure' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/benchmarking.rb:66:in
perform_action_without_rescue’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/rescue.rb:83:in perform_action' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/base.rb:430:in
send’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/base.rb:430:in process_without_filters' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/filters.rb:624:in
process_without_session_management_support’
h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/
action_controller/session_management.rb:114:in process' h:/ruby/lib/ruby/gems/1.8/gems/actionpack-1.13.1/lib/ action_controller/base.rb:330:in
process’
h:/ruby/lib/ruby/gems/1.8/gems/rails-1.2.1/lib/dispatcher.rb:41:in
dispatch' h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/bin/scgi_service: 23:in
process_request’
h:/ruby/lib/ruby/1.8/thread.rb:135:in synchronize' h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/bin/scgi_service: 21:in
process_request’
h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:291:in
read_header' h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:253:in
handle_client’
h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:234:in
initialize' h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:234:in
new’
h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:234:in
handle_client' h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:188:in
listen’
h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:186:in
initialize' h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:186:in
new’
h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:186:in
listen' h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/lib/scgi.rb:412:in
run’
h:/ruby/lib/ruby/gems/1.8/gems/scgi_rails-0.4.3/bin/scgi_service:
61
h:/ruby/bin/scgi_service:18:in `load’
h:/ruby/bin/scgi_service:18