Действие обновления рельсов не позволяет проверить параметры

#ruby-on-rails #ruby #put

Вопрос:

Я создаю API Rails и обнаружил, что запрос put проходит без необходимых параметров. Это странно для меня, так как приложение не разрешает отправлять запрос без параметров. Более того, когда я пытаюсь обновить расходы без атрибутов через консоль Rails, это не удается. Но через запрос почтальона/ЛОКОНА успешно проходит

Контроллер выглядит следующим образом:

 class SpendingsController < ApplicationController
  before_action :find_spending, only: %i[show update destroy]

  def create
    spending = Spending.new(spending_params)
    spending.user = current_user
    spending.category = Category.find_by(id: spending_params[:category_id])

    if spending.valid?
      spending.save
      render json: SpendingSerializer.new(spending), status: :ok
    else
      render json: ActiveRecordErrorsSerializer.new(spending), status: :bad_request
    end
  end

  def index
    spendings = Spending.where(user_id: current_user.id).order("#{sort_spendings}")
    total_value = Spending.where(user_id: current_user.id).pluck(:amount).sum

    render json: {spendings: SpendingSerializer.new(spendings), total_amount: total_value}, status: :ok
  end

  def show
    if @spending.valid?
      render json: SpendingSerializer.new(@spending), status: :ok
    else
      render json: ActiveRecordErrorsSerializer.new(@spending), status: :not_found

    end
  end

  def update
    if @spending.valid?
      @spending.update(spending_params)
      render json: SpendingSerializer.new(@spending), status: :ok
    else
      render json: ActiveRecordErrorsSerializer.new(@spending), status: :bad_request
    end
  end

  def destroy
    if @spending.destroy
      head :no_content
    else
      render json: ActiveRecordErrorsSerializer.new(@spending), status: :not_found
    end
  end

  private

  def spending_params
    params.require(:spending).permit(:description, :amount, :category_id)
  end

  def find_spending
    begin
      @spending = Spending.find(params[:id])
    rescue ActiveRecord::RecordNotFound
      render json: {errors: "Spending with id #{params[:id]} not found"}, status: :not_found
    end
  end

  def sort_spendings
    sort = { sort_by: "created_at", sort_dir: "desc"}
    sort[:sort_by] = params[:sort_by].split(" ").first if params[:sort_by].present?
    sort[:sort_dir] = params[:sort_by].split(" ").last if params[:sort_by].present?
    sort.values.join(" ")
  end
end
 

И моя модель:

 class Spending < ApplicationRecord
  belongs_to :user
  belongs_to :category
  validates :description,
            presence: true
end
 

У меня действительно нет идей, почему это происходит. Есть какие-нибудь догадки, с чем это может быть связано?

Комментарии:

1. ПОМЕЩЕННЫЙ запрос не должен содержать все необходимые параметры, поскольку он обновляет только уже существующие записи, и в этих записях уже установлены все необходимые атрибуты.

2. Большое спасибо! Я только что понял, что пытался уловить не ошибку, а стандартное поведение, думаю, я слишком напряжен с тестовым заданием для первой работы по кодированию. И я действительно имею в виду это, когда говорю большое спасибо!

Ответ №1:

Первое, что я заметил, — это ваш update метод. Вы проверяете проверку перед обновлением модели. @spending.valid? в этом случае всегда возвращается значение true. Мое предложение изменить его. @spending.update(spending_params) возвращает true, если обновление прошло успешно, и false, если оно завершилось неудачно.

 def update
  if @spending.update(spending_params)
    render json: SpendingSerializer.new(@spending), status: :ok
  else
    render json: ActiveRecordErrorsSerializer.new(@spending), status: :bad_request
  end
end
 

created метод также может быть оптимизирован. Вам не нужно искать и назначать category отдельно. Он будет назначен как все spending_params .

 def create
  spending = Spending.new(spending_params)
  spending.user = current_user

  spending.save
    render json: SpendingSerializer.new(spending), status: :ok
  else
    render json: ActiveRecordErrorsSerializer.new(spending), status: :bad_request
  end
end