Katie M
Katie M

Reputation: 1131

Rails 4 - How to set db attribute on create

This seems like a dumb question, but how do I update a database field from a model method? The incident.incident_number value is displayed on all the forms and emails, but is NULL in the database:

incident.rb

 validate :incident_number, :on => :save

  def incident_number
    (self.created_at.strftime("%Y") + self.created_at.to_date.jd.to_s + self.id.to_s).to_i
  end

incidents_controller.rb

  def create
    @incident = Incident.new(incident_params)
    @incident.user_id = current_user.id
    @incident.state_id = 1
    respond_to do |format|
      if @incident.save
        IncidentMailer.new_incident_notification(@incident).deliver
        format.html { redirect_to my_incidents_path, notice: 'Incident was successfully created.' }
        format.json { render action: 'show', status: :created, location: @incident }
      else
        format.html { render action: 'new' }
        format.json { render json: @incident.errors, status: :unprocessable_entity }
      end
    end
  end

Upvotes: 1

Views: 60

Answers (1)

Momer
Momer

Reputation: 3237

Your current method doesn't persist to the database, it just runs the logic every time the method is called.

There are a number of ways to do this - either via write_attributes (works well in before_save)

before_save :update_incident_number, if: Proc.new { conditional_logic_here } 
...
def update_incident_number
  write_attribute(:incident_number, new_value)
end

Or, use update_attribute(s)

after_commit :update_incident_number, if: Proc.new { conditional_logic } 
...
def update_incident_number
  self.update_attribute(:incident_number, new_value)
end

There are a few ways to skin this cat, try a few and see which you prefer based on what callbacks are triggered, and how they deal with your record / changed properties.

Upvotes: 1

Related Questions