Ruby on Rails: составьте атрибут модели из виртуальных атрибутов - PullRequest
2 голосов
/ 26 июля 2010

У меня есть атрибут имя модели Person.

Я хочу использовать html-форму с полями: first_name и фамилия :

<%= f.text_field first_name%>
<%= f.text_field surname%>

И я хочу объединить эти виртуальные атрибуты с атрибутом модели name .

Какой лучший способ сделать это?

Я пыталсяиспользовать составе_фо , но не удалось ...

class Person < ActiveRecord::Base
  composed_of :name, :class_name => 'Name', :mapping => %w(name output_name)
end

class Name
  attr_reader :output_name
  def initialize(first_name, surname)
    @output_name = first_name + surname
  end
end

@person.attributes= {"name(1s)" => 'Alex', "name(2s)" => 'Bolduin' }
@person.name.should == 'Alex Bolduin'

expected: "Alex Bolduin",
got: #<Name:0x000000049d4c08 @output_name="Alex Bolduin"> (using ==)

Я использую Ruby on Rails 3, но я думаю, что решение аналогично для Rails 3 и Rails 2.3

1 Ответ

7 голосов
/ 27 июля 2010

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

class Person < ActiveRecord::Base
    def name
      "#{self.first_name} #{self.surname}"
    end

    def name=(fullname)
      first,last = fullname.split(' ')  # or some smarter way to split
      self.first_name = first
      self.surname = last
    end
end

Он должен быть доступен так же, как и любой другой столбец, и при попытке установить nameон просто вызовет методы установки для first_name и surname.


Если вы хотите сделать обратное, вы все равно можете использовать тот же трюк:

class Person < ActiveRecord::Base
    def first_name
      name.split(' ')[0]
    end

    def surname
      name.split(' ')[1]
    end

    def first_name=(first)
      name = [first, name.split(' ')[1]].join(' ')
    end

    def surname=(sname)
      name = [name.split(' ')[0], sname].join(' ')
    end

end

Единственное, что может быть плохим в этом - то, что манипулирование строками происходит один раз для каждого чтения и дважды для каждой записи.В качестве альтернативы вы можете перехватить что-то в контроллере, добавив что-то подобное для создания / обновления до @person.save:

@person.name = [first_name, surname].join(' ')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...