Umang Raghuvanshi
Umang Raghuvanshi

Reputation: 1258

Virtual attributes Rails - Unknown Attribute Error

I'm making a Rails 4 application. Each incident belongs to a user. Each incident has many events. I want that I can create an Incident with current_user.incidents.new and pass it an attribute message which exists in the Event model. On creation, I wish to create a new event with the said message.

Here's my Incident model.

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

But, when I run @i = Incident.new(message: 'something'), I get ActiveRecord::UnknownAttributeError: unknown attribute 'message' for Incident.

Please help me figure this out.

Upvotes: 4

Views: 2358

Answers (2)

Daiku
Daiku

Reputation: 1227

Because your Incident model inherits from ActiveRecord::Base, it inherits the constructor. The ActiveRecord constructor only accepts model attributes (db columns) as params. You are trying to call an arbitrary instance method. You could create a class method that creates an instance then adds the message:

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

Upvotes: 1

Matt
Matt

Reputation: 14038

The problem is that you're passing the values to the default ActiveRecord::new method for Incident, which won't care about your getters, setters and accessors, it goes straight to the columns.

Some people override or adapt the build method that can implement clever logic like you require, without affecting the base initialize method.

Upvotes: 2

Related Questions