模型中的自定义方法以返回对象
时间: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"?

