Skip to content

Error with has_and_belongs_to_many association #6

Closed
torsakch opened this Issue Feb 8, 2012 · 13 comments

2 participants

@torsakch
torsakch commented Feb 8, 2012

When I use the has_and_belongs_to_many association in the model having act_as_tenant, I got the internal server error. Actually, it is an NoMethodError (undefined method ... ). So, I don't the problem. Please help me to verify. Thanks

@torsakch
torsakch commented Feb 8, 2012

Note that when I put the acts_as_tenant(:account) before the :has_and_belongs_to_many association, the problem doesn't occur. But when I put it below the :has_and_belongs_to_many association in the model. The problem occurs.

The reason that I want to put it below the :has_and_belongs_to_many association is that I want to make an inheritance of the model and the child model will be assigned to acts_as_tenant. So, the code in the parent model will be executed first and following by the child model code.

Could you tell me how to solve this problem? Thank you in advance.

@ErwinM
Owner
ErwinM commented Feb 9, 2012

Could you post your model code for me?

@torsakch

Thank you for replying me. Here are my models.

class Account < ActiveRecord::Base
has_many :users
end

class User < ActiveRecord::Base
belongs_to :account
has_and_belongs_to_many :roles
end

class Role < ActiveRecord::Base
has_and_belongs_to_many :users
end

class Member < User
acts_as_tenant(:account)
end

@ErwinM ErwinM was assigned Feb 11, 2012
@ErwinM
Owner
ErwinM commented Feb 11, 2012

In the code above acts_as_tenant has nothing to do with the HABTM association: acts_as_tenant is defined on the member model which does not have an HABTM association.

Can you also post the code that triggers the 'undefined method'-error, or post the stack trace?

@torsakch

I have tracked to the code and the error comes from the model_extensions.rb.

71 reflect_on_all_associations.each do |a|
72 unless a == reflection || a.macro == :has_many || a.macro == :has_one || a.options[:polymorphic]
73 # check if the association is aliasing another class, if so
74 # find the unaliased class name
75 association_class = a.options[:class_name].nil? ? a.name.to_s.classify.constantize : a.options[:class_name].constantize
76 validates_each a.foreign_key.to_sym do |record, attr, value|
77 # Invalidate the association unless the parent is known to the tenant or no association has
78 # been set.
79 record.errors.add attr, "is invalid (Acts_as_Tenant)" unless value.nil? || association_class.where(:id => value).present?
80 end
81 end
82 end

I think in this block code, it passes through the "unless" block because the association is HABTM and it gets an error in the "validates_each" block.

@torsakch

One more thing, it happens just only on the update operations. (eg. update_attributes)

@ErwinM
Owner
ErwinM commented Feb 12, 2012

I think this is happening because your Role model is not scoped to account. Could you try scoping the Role model to account as well and see if you get the error?

@torsakch

Thank you so much for answering. In the role model, why I need to scope to :account, because I don't need :roles table to be scoped. It is generic for every tenant. I mean for every user they will use the same roles in the table.

@ErwinM
Owner
ErwinM commented Feb 12, 2012

yup, I understand that. It would help me figure out if that's the problem though..

@torsakch

Right now, my code is changed. I decided to remove the roles table from my project and use the role_mask attributes instead.

Note that... If I add "|| a.macro == :has_and_belongs_to_many" to the line 72. It can solve the problem too. But I am not sure whether it affects the security? or am I doing the right thing.

Note2. in the error it said "undefined method user_id". So, I don't that why it involves with user_id.

@torsakch
torsakch commented Mar 5, 2012

@ErwinM When I added the account_id in Role, the problem is disappeared. I think the problem has occur in case of the :belongs_to macro. So what should I do?

@ErwinM
Owner
ErwinM commented Mar 5, 2012

@torsakch I think it's actually a problem with the gem: the gem currently assumes that every association will always be scoped to the tenant. In practice, a scoped model can be associated with a non-scoped model (like in your case).

I will need to fix this in the code. I'll try to push out an update tonight.

@ErwinM
Owner
ErwinM commented Apr 13, 2012

This should actually be fixed now. Let me know if it isn't.

@ErwinM ErwinM closed this Apr 13, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.