-
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, 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.