Пользовательский метод в модели для возврата объекта - PullRequest
1 голос
/ 30 сентября 2008

В базе данных у меня есть поле с именем '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].

Ответы [ 3 ]

4 голосов
/ 30 сентября 2008

Это относительно просто; вы получаете массив, потому что код строит его. Если бы вы хотели вернуть объект, вы бы сделали что-то вроде этого:

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
2 голосов
/ 30 сентября 2008

Или, если вы хотите избежать модельного класса, вы можете сделать что-то странное:

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 голос
/ 03 октября 2008

на немного другой гвоздь.

Идея использования метода класса для этого кажется неправильной с точки зрения ОО.

Вы должны действительно изменить его, чтобы он работал из метода экземпляра.

  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 в качестве внешнего ключа, у вас будет

Организация класса принадлежат: человек конец

тогда, когда у вас есть организация, вы можете пойти

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_by_person_id' везде, где вы действительно хотите написать 'find'?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...