Как добавить виртуальный атрибут к модели в Ruby on Rails?

Я работаю над приложением RubyonRails/ActiveAdmin. Моя версия RoR - 4.2.5, а версия AA - 1.0.0. У меня есть модель Message следующим образом.

class Message < ActiveRecord::Base

  belongs_to :user
  validates :user, :content, presence: true

  def palindrome
    # return true/false
  end

end

Как вы видите, я хочу иметь атрибут "только для чтения" palindrome, который зависит только от сообщения content. Я хочу, чтобы этот атрибут обрабатывался точно как обычный атрибут. В обычном я имею в виду, когда я получаю сообщения через rails console или запрос json формата сообщений, я хочу увидеть атрибут palindrome в списке. Я также хотел бы иметь фильтр для сообщения по этому атрибуту.

Я не уверен, как я мог это достичь.

Ответ 1

В вашей модели вы можете записывать атрибуты-атрибуты (читатель/писатель) для вашего атрибута виртуального атрибута palindrome следующим образом:

# attr_reader
def palindrome
  self[:palindrome]
end

# attr_writer
def palindrome=(val)
  self[:palindrome] = val
end

# virtual attribute
def palindrome
  #return true/false
end

И поскольку вы используете Rails 4, вам нужно присваивать белый список атрибуту palindrome, как и любой другой атрибут модели, в вашем сильном определении параметра внутри вашего контроллера, чтобы можно было массово присвоить значение palindrome. Что-то вроде этого:

# your_controller.rb
private

def your_model_params
  params.require(:message).permit(:palindrome)
end

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

Примечание:

Виртуальный атрибут автоматически не будет отображаться в списке параметров. Но вы должны иметь доступ к нему через консоль Rails следующим образом: Message.new.palindrome. Кроме того, вы можете открыть этот виртуальный атрибут в своем JSON API, например, если вы используете Active Serializer, вы можете: attribute palindrome в своем MessageSerializer и то palindrome будет отображаться в JSON API.

Ответ 2

Ruby фактически позволяет вам создавать виртуальные атрибуты таким образом, что избавляет вас от необходимости вручную создавать методы получения и установки:

attr_reader   :palindrome #getter
attr_writer   :palindrome #setter
attr_accessor :palindrome #both

Вы также можете передать несколько аргументов:

attr_accessor :palindrome, :foo, :bar

Документация для этого не самая большая.

Ответ 3

Есть ли способ, когда мы визуализируем в xml, чтобы убедиться, что виртуальный атрибут palindrome также отображается, а не только столбцы базы данных?