uno
uno

Reputation: 1481

Customize notice message for each parameter on update?

Goal: to have a unique message per either each parameter or set of paramters.

I have this code in my controller update:

def update
    @order = Order.find(params[:id])
    respond_to do |format|
      if @order.update_attributes(order_status)
        # if @order.changed == [:order_status]
          format.html { redirect_to @order, notice: 'Order was successfully cancelled.' }
          format.json { render :show, status: :ok, location: @order }
      #   else
      #     format.html { render :edit }
      #     format.json { render json: @order.errors, status: :unprocessable_entity }
      #   # end
      # end
    elsif @order.update(order_params)
        format.html { redirect_to @order, notice: 'Order was successfully updated.' }
        format.json { render :show, status: :ok, location: @order }
      else
        format.html { render :edit }
        format.json { render json: @order.errors, status: :unprocessable_entity }
      end
    end
  end

private

def order_params
      params.require(:order).permit(:name, :name_2, :email, :phone_number)
    end

    def order_status
      params.require(:order).permit(:order_status)
    end

Though, no matter which parameter i update, I always get the message "'Order was successfully cancelled.", even when I don't update :order_status at all.

I have tried many many combinations but I cannot get a unique message to work. Everything still updates, just not with the messages i want. I have tried not using elsif, not defining @order, different orders, user .update and .update_attributes, using @order.update(params[:order_status]), etc.

What can I do here to have custom messages?

Upvotes: 1

Views: 57

Answers (2)

Tom
Tom

Reputation: 1320

if @order.update(order_status)
  if @order.order_status_previously_changed?
    format.html { redirect_to @order, notice: 'Order was successfully cancelled.' }
    ...

Rails uses ActiveRecord::Dirty to keep track of changes to the model during and after updates. You can also use it to see what attributes were changed (@order.order_status_changed?), what they were originally, and what they changed too (@order.order_status_changed?(from: :open, to: :cancelled)). This would give you finer control over the response. Note that the last two examples would need to be implemented before the order object is saved.

Upvotes: 1

max pleaner
max pleaner

Reputation: 26778

Say you don't provide a value for params[:order_status]. Then the method order_status will return an empty hash. Well, technically it's an instance of ActionController::Parameters, but is behaves like a hash:

ActionController::Parameters.superclass
# => ActiveSupport::HashWithIndifferentAccess

ActionController::Parameters.superclass.superclass
# => Hash

params = ActionController::Parameters.new(order: {foo: "bar"})
params.require(:order).permit(:order_status)
# => {}

Running update or update_attributes with an empty hash will be succesful. That's why your first if condition is being met. As a fix, you can do something quite simple:

if order_stats.present? && @order.update_attributes(order_status)

The Object#present? method will check that object is truthy and non-empty. It's the opposite of Object#blank?

Upvotes: 0

Related Questions