0

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

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

然而,这并不是一个很好的设计,因为调用filter_dataReport 对象会返回一个子对象。如何允许Report具有子对象的所有属性?

我正在考虑继承(即,Report 继承了 UserData 和 ReportConfig,但它不起作用)。还有哪些其他设计模式可以解决我的问题?

4

1 回答 1

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

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

于 2013-08-16T05:34:57.837 回答