2008-09-29 31 views
1

在數據庫中,我有一個名爲「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]來使用 。

謝謝你的時間。
Silviu

p.s我是rails和ruby的新手。我有一個C背景。

回答

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 
+0

工程就像一個魅力;) – 2008-09-29 21:04:35

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" 

這就像魔法!

+1

任何情況下,你可以想到什麼時候使用這種方法在邏輯上比回答的方法更好? – junkforce 2008-09-30 04:09:45

+0

對於這些類型的解決方案,我開始喜歡Ruby – 2008-09-30 10:17:20

1

略有不同的粘性。

從面向對象的角度來看,使用類方法做這件事的想法是錯誤的。

你應該真的重構這個,以便它從一個實例方法。

 
    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對象有一個「處理」,所以不必自己構造它。

舉例來說,如果你有另一個類,在這裏引用爲person_id作爲外鍵,你就必須

類組織 belongs_to的:人 結束

話,那就是你有一個組織,你可以去

 
organisation.person.personal_information_module 

是的,我知道,得墨忒耳突破,所以這將是更好地包裝在一個委託

 
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'?

相關問題