2015-09-22 5 views
2

Je crée une application Rails 4. Chaque incident appartient à un user. Chaque incident has many events. Je veux que je puisse créer un incident avec current_user.incidents.new et lui transmettre un attribut message qui existe dans le modèle d'événement. En création, je souhaite créer un nouvel événement avec le dit message.Attributs virtuels Rails - Attribut inconnu Erreur

Voici mon modèle d'incident.

class Incident < ActiveRecord::Base 
    # The 'incident' model. 
    # Incidents are created by Users (belongs_to :user) 
    # Incidents may be public or private. 
    # Incidents have many events (identified, fixing, etc.) 

    belongs_to :user 
    has_many :events 
    validates :name, presence: true, length: {maximum: 256} 
    validates_presence_of :component 
    validates_presence_of :public 
    validates_presence_of :user_id 

    attr_accessor :message 
    validates_associated :message, presence: true 

    def message 
    Event.find_by_incident_id(self.id).message 
    end 

    def message=(value) 
    self.events.new(message: value, status: self.status) 
    end 

    private 
    def incident_params 
     params.require(:incident).permit(:name, :status, :user_id, :message) 
    end 

end 

Mais, quand je lance @i = Incident.new(message: 'something'), je reçois ActiveRecord::UnknownAttributeError: unknown attribute 'message' for Incident.

S'il vous plaît me aider à comprendre cela.

+2

Vous aurez besoin [ 'accepts_nested_attributes_for'] (http://apidock.com/rails/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for) de telle sorte que l'Incident sait quoi faire avec cet attribut. alors votre 'params' devrait être' .permit (: nom,: statut,: user_id, event_attributes: [: message]) 'Cela nécessitera également des changements à votre formulaire pour utiliser' fields_for' qui fait référence à un nouvel événement. [Ce tutoriel] (https://gorails.com/episodes/forum-nested-attributes-and-fields-for) pourrait aider mieux que mon explication. – engineersmnky

Répondre

2

Le problème est que vous passez les valeurs à la méthode par défaut ActiveRecord::new pour Incident, qui ne se soucient pas de vos getters, setters et accesseurs, goes straight to the columns.

Certaines personnes remplacent ou adaptent le build method qui peut implémenter une logique intelligente comme vous le souhaitez, sans affecter la méthode de base initialize. Comme votre modèle Incident hérite de ActiveRecord :: Base, il hérite du constructeur.

+1

Merci. Cela a sauvé ma journée. –

1

Le constructeur ActiveRecord accepte uniquement les attributs de modèle (colonnes db) en tant que params. Vous essayez d'appeler une méthode d'instance arbitraire. Vous pouvez créer une méthode de classe qui crée une instance ajoute le message:

def self.create_with_message(msg) 
    i = Incident.new 
    i.message(msg) 
    return(i) 
end 
+0

Merci. Mais je suis plus à l'aise avec la réponse de Matt. Semble plus propre. Mais même cela fonctionne. –