-
Notifications
You must be signed in to change notification settings - Fork 9
Private Methods
In many ways, flex_columns
models its behavior after ActiveRecord — for example, automatic generation of attribute methods. However, flex_columns
offers an option ActiveRecord doesn't: you can make attribute methods private by default.
This is a deliberate choice, as ActiveRecord's "everything is public" design choice makes true encapsulation very difficult — any code, anywhere in the system, can easily set any ActiveRecord column to any value at all. By allowing fields to be private, flex_columns
can help ensure that access is only done via valid code paths.
If you add :visibility => :private
to a particular field in a flex column, then the generated methods for that column will be marked as private. If you add :visibility => :private
to the flex column itself, then all generated methods for that column will be marked as private, unless you individually mark them as public.
For example:
class User < ActiveRecord::Base
flex_column :user_attributes do
field :maximum_emails_per_week, :visibility => :private
field :background_color
end
flex_column :more_attributes, :visibility => :private do
field :foo
field :bar, :visibility => :public
end
end
my_user = User.find(...)
my_user.maximum_emails_per_week # NoMethodError: private method 'maximum_emails_per_week' called
my_user.user_attributes.maximum_emails_per_week # NoMethodError: private method 'maximum_emails_per_week' called
my_user.maximum_emails_per_week = 3 # NoMethodError: private method 'maximum_emails_per_week=' called
my_user.user_attributes.maximum_emails_per_week = 3 # NoMethodError: private method 'maximum_emails_per_week=' called
my_user.background_color # fine
my_user.foo # NoMethodError: private method 'foo' called
my_user.foo = 3 # NoMethodError: private method 'foo=' called
my_user.bar # fine
my_user.bar = 'some value' # fine
Note that if you want to use Ruby's private
or public
method to change the visibility of one of these methods (for example, to make a reader public, but a writer private), it's slightly tricky. So that method overriding will work properly, these methods are actually defined on a module that's include
d into the flex-column class and ActiveRecord class; you can't simply say private :foo
, for example. Instead, you must first override the method (a simple call to super
works fine), and then make that method public or private.