Are class variables a good way to set the context for a class instance in a Rails application?
We are building a rails application that manages members of clubs. As such there is a Member model and a Club model. Since a member can belong many clubs and a club can have many members, there is a HABTM association between them.
The difficulty we are having is determining the club context in which a member instance exists. For example, to set a member dues status as “paid”, we need to know for which club the dues have been paid.We would like the controller to simply set something like
@member.paid=true
without having to fuss about remembering to set the club every time we update a member.
The solution we have come up with sets a class variable in Member.
application_controller.rb
class ApplicationController < ActionController::Base
before_filter :set_current_club
def set_current_club
Member.current_club = current_club
end
...
end
As a somewhat contrived example, imagine the each club contains an array of members who have paid their dues. We would then have.
member.rb
class Member < ActiveRecord::Base
cattr_accessor :current_club
...
def paid=(status)
if (status)
@@current_club.paid_members << self
else
@@current_club.paid_member.delete(self)
end
end
def paid?
@@current_club.paid_members.include?(self)
end
...
end
The worry is that, by setting the current_club as a Member class variable in an ApplicationController before_filter, is it possible that there could be conflicts and race conditions when having more than one club accessing the application at the same time?
We did some debugging testing in our development environment, and showed that the @@current_club attribute in the model (Member.current_club) was always nil when entering the before_filter method in the ApplicationController. In other words, there was no evidence that current_club was affected by previous requests when serving a new request. So I think we are OK and that setting a model class variable from Application Controller is scoped to the user’s session. But I would like to be sure before going ahead with this approach.”
If you have the current_club property, which I assume is some form of a session variable, there is absolutely no need for the above code.
To grab the Club record of a Member while having the current_club variable, simply iterate through all of the clubs associated with that member, find the record matching the current club and you’re done.
Something like this:
You don’t need to worry about race conditions, weirdness due to values hanging around and all that crap.