简体   繁体   中英

Rails Validates don't work on update

I've got a problem with validators. I have a "contact" model which contains two fields firstname and lastname and I want both required on CREATE and UPDATE method. When I create a record with no data, the server return me a 422 and do the rollback. This is ok. But when I update a record the server don't return the error 422 although the server does the rollback. And I need the return of the error to manage it on the client side.

So I use validators like this :

class Contact < ActiveRecord::Base
    validates :lastname,    presence: true
    validates :firstname, presence: true
end

and my controller is:

class ContactsController < ApplicationController

    respond_to :json

    def index
        respond_with Contact.all
    end

    def create
        respond_with Contact.create(contact_params)
    end

    def show
        respond_with Contact.find(params[:id])
    end

    def edit
        respond_with Contact.find(params[:id])
    end

    def update
        respond_with Contact.find(params[:id]).update(contact_params)
    end

    def destroy
        respond_with Contact.find(params[:id]).destroy
    end

    private
        def contact_params
            params.require(:contact).permit(:lastname, :firstname, :position)
        end

end

I have a serializer:

class ContactSerializer < ActiveModel::Serializer
    attributes :id, :lastname, :firstname, :created_at, :updated_at
end

Someone could help me, please ?

Thanks by advance.

Contact.find(params[:id]).update(contact_params)

returns a Boolean, hence you are telling Rails to render a boolean (which will render a 200 with the boolean serialized as JSON).

Same for destroy. You need to pass the instance.

def update
  contact = Contact.find(params[:id])
  contact.update(contact_params)
  respond_with contact
end

def destroy
  contact = Contact.find(params[:id])
  contact.destroy
  respond_with contact
end

It's also a good habit to extract the finder in a before_action .

before_action :find_contact

def update
  @contact.update(contact_params)
  respond_with @contact
end

def destroy
  @contact.destroy
  respond_with @contact
end

protected

def find_contact
  @contact = Contact.find(params[:id])
end

You can refactor the other actions to remove the duplicate finder.

you can try the following code, it could be tempo fix

def update
  @contact = Contact.find params[:id]
  @contact.update contact_params
  if @contact.errors.count > 0
    # do you like
  else
    respond_with @contact
  end
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM