Rails中包含输入数据和配置的报表的设计模式

时间:2013-08-16 03:55:01

标签: ruby-on-rails design-patterns

我需要公开展示用户个人资料,用户可以在其中选择要展示的内容和不展示的内容。我的设计是:

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,但它不起作用)。什么是其他设计模式可以适应我的问题?

1 个答案:

答案 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

我不知道详细要求,只是尝试提供一个选项。希望它有所帮助:)