我需要公开展示用户个人资料,用户可以在其中选择要展示的内容和不展示的内容。我的设计是:
class Report < ActiveRecord::Base
belongs_to :user_data
belongs_to :report_config
delegate :show_name, :show_address, :to => :report_config
delegate :name, :address, :to => :user_data
def filter_data
report = self.user_data
report.name = nil if show_name.false?
report.address = nil if show_address.false?
return report
end
end
class UserData < ActiveRecord::Base
has_many :report
end
class ReportConfig < ActiveRecord::Base
has_many :report
end
但是,这不是一个非常好的设计,因为在Report对象上调用filter_data
会返回一个子对象。如何允许Report
拥有子对象的所有属性?
我正在考虑继承(即,Report继承了UserData和ReportConfig,但它不起作用)。什么是其他设计模式可以适应我的问题?
答案 0 :(得分:1)
您可以使用ruby中的元编程委派用户模型的所有属性。
class Report < ActiveRecord::Base
belongs_to :user_data
belongs_to :report_config
delegate :show_name, :show_address, :to => :report_config
self.class_eval do
#reject the attributes what you don't want to delegate
UserData.new.attribute_names.reject { |n| %w(id created_at updated_at).include?(n) }.each do |n|
delegate n , to: :user_data
end
end
def filter_data
name = nil if show_name.false?
address = nil if show_address.false?
end
end
使用它时,您只需初始化报告:
report = Report.find_by_user_data_id(YOUR USER DATA ID)
report.filter_data
report.name
report.address
report.....
另一方面,你真的需要一个报告对象吗?那么只使用你的UserData和ReportConfig?
class UserData < ActiveRecord::Base
belongs_to :report_config
delegate :show_name, :show_address, :to => :report_config
def report_name
name if show_name
end
def report_address
address if show_address
end
end
class ReportConfig < ActiveRecord::Base
end
我不知道详细要求,只是尝试提供一个选项。希望它有所帮助:)