模型中的自定义方法以返回对象
时间:2020-03-06 14:53:42 来源:igfitidea点击:
在数据库中,我有一个名为" body"的字段,其中包含XML。这
我在模型中创建的方法如下所示:
def self.get_personal_data_module(person_id) person_module = find_by_person_id(person_id) item_module = Hpricot(person_module.body) personal_info = Array.new personal_info = {:studies => (item_module/"studies").inner_html, :birth_place => (item_module/"birth_place").inner_html, :marrital_status => (item_module/"marrital_status").inner_html} return personal_info end
我希望函数返回一个对象而不是一个数组。所以我可以
使用Module.studies代替Model [:studies]。
感谢时间。
西尔维
附言:我是Rails和ruby的新手。我有C背景。
解决方案
这是相对简单的。我们会得到一个Array,因为代码正在构建一个。如果我们想返回一个对象,则可以执行以下操作:
class PersonalData attr_accessor :studies attr_accessor :birth_place attr_accessor :marital_status def initialize(studies,birth_place,marital_status) @studies = studies @birth_place = birth_place @marital_status = marital_status end end
翻译代码如下所示:
def self.get_personal_data_module(person_id) person_module = find_by_person_id(person_id) item_module = Hpricot(person_module.body) personal_info = PersonalData.new((item_module/"studies").inner_html, (item_module/"birth_place").inner_html, (item_module/"marital_status").innner_html) return personal_info end
或者,如果我们想避免模型类,则可以做一些奇怪的事情:
class Hash def to_obj self.inject(Object.new) do |obj, ary| # ary is [:key, "value"] obj.instance_variable_set("@#{ary[0]}", ary[1]) class << obj; self; end.instance_eval do # do this on obj's metaclass attr_reader ary[0].to_sym # add getter method for this ivar end obj # return obj for next iteration end end end
然后:
h = {:foo => "bar", :baz => "wibble"} o = h.to_obj # => #<Object:0x30bf38 @foo="bar", @baz="wibble"> o.foo # => "bar" o.baz # => "wibble"
就像魔术!
略有不同。
从面向对象的角度来看,使用类方法执行此操作的想法是错误的。
我们应该真正重构它,以便它可以通过实例方法工作。
def personal_data_module item_module = Hpricot(body) { :studies => (item_module/"studies").inner_html, :birth_place => (item_module/"birth_place").inner_html, :marrital_status => (item_module/"marrital_status").inner_html } end
然后,在需要使用它的地方,而不是做...。
Foobar.get_personal_data_module(the_id)
你会做
Foobar.find_by_person_id(the_id).personal_data_module
这看起来更糟,但实际上,多数民众赞成在某种程度上是虚假的,
从其他对象引用此对象,实际上我们在person对象上会有一个" handle",因此不必自己构造它。
例如,如果我们有另一个类,其中将person_id引用为外键,则我们将拥有
班级组织
归属于:person
结尾
然后,如果我们有组织,就可以去
organisation.person.personal_information_module
是的,我知道,这会破坏demeter,因此最好将其包装在委托中
class Organisation belongs_to :person def personal_info_module person.personal_info_module end end
然后从控制器代码中,我们可以说
organisation.personal_info_module
完全不用担心它来自何处。
这是因为'personal_data_module'实际上是该类的属性,而不是通过类方法访问的东西。
但这也带来了一些问题,例如person_id是该表的主键吗?这是表的主键不称为" id"的遗留情况吗?
如果是这样,我们是否已将此事告知ActiveRecord,还是必须在真正要写"查找"的地方使用" find_by_person_id"?