web-dev-qa-db-fra.com

Comment ajouter un attribut virtuel à un modèle dans Ruby on Rails?

Je travaille sur une application RubyonRails/ActiveAdmin. Ma version RoR est 4.2.5 et la version AA est 1.0.0. J'ai un modèle Message comme suit.

class Message < ActiveRecord::Base

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

  def palindrome
    # return true/false
  end

end

Comme vous le voyez, je veux avoir un attribut en lecture seule palindrome qui ne dépend que du content du message. Je veux que cet attribut soit traité exactement comme un attribut normal. Par normal, je veux dire quand je récupère des messages via Rails console ou demande json le format des messages, je veux voir un attribut palindrome dans la liste. Je voudrais également avoir un filtre pour le message par cet attribut.

Je ne sais pas comment pourrais-je y parvenir.

20
moorara

Dans votre modèle, vous pouvez écrire des accesseurs d'attribut (lecteur/écrivain) pour votre attribut virtuel palindrome de cette façon:

# attr_reader
def palindrome
  self[:palindrome]
end

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

# virtual attribute
def palindrome
  #return true/false
end

Et, comme vous utilisez Rails 4, vous devez mettre sur liste blanche l'attribut palindrome comme tout autre attribut de modèle dans votre définition de paramètre fort à l'intérieur de votre contrôleur afin de pouvoir affecter en masse le valeur de palindrome. Quelque chose comme ceci:

# your_controller.rb
private

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

Jetez un oeil à ce RailsCast sur les attributs virtuels . Bien que ce soit un peu ancien, il serait utile pour les concepts.

Remarque:

Un attribut virtuel n'apparaîtra pas automatiquement dans la liste des paramètres. Mais, vous devriez pouvoir y accéder via la console Rails comme ceci: Message.new.palindrome. En outre, vous pouvez exposer cet attribut virtuel dans votre API JSON, par exemple si vous utilisez Active Model Serializer , vous pouvez avoir: attribute palindrome dans votre MessageSerializer puis palindrome sera exposé à l'API JSON.

14
K M Rakibul Islam

Ruby vous permet en fait de créer des attributs virtuels de cette façon, ce qui vous évite d'avoir à créer manuellement des méthodes getter et setter:

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

Vous pouvez également passer plusieurs arguments également:

attr_accessor :palindrome, :foo, :bar

Le documentation pour cela n'est pas le plus grand.

23
Brent Eicher