在数据库中,我有一个名为“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]。
答案 0 :(得分:4)
这相对简单;你得到一个数组,因为代码正在建立一个。如果你想返回一个对象,你可以这样做:
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
答案 1 :(得分:2)
或者,如果你想避开一个模型类,你可以做一些奇怪的事情:
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"
就像魔术一样!
答案 2 :(得分:1)
略有不同的大头钉。
从OO的角度来看,使用类方法执行此操作的想法是错误的。
你应该重构这个,以便它可以从实例方法中运行。
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作为外键引用,那么您将拥有
班级组织 belongs_to: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'的地方使用'find_by_person_id'?