Rails 更新操作无法检查参数

Rails update action fails to check params

我正在构建一个 Rails API 并发现放置请求在没有必需参数的情况下通过。这对我来说很奇怪,因为应用程序不允许没有参数的 post 请求。此外,当我尝试通过 Rails 控制台更新没有属性的支出时,它失败了。但是通过 Postman/CURL 请求成功通过

控制器看起来像这样:

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

我真是没脑子,怎么会这样。猜猜这与什么有关?

我首先注意到的是您的 update 方法。在更新模型之前检查验证。在这种情况下,@spending.valid? 始终 returns 为真。我的建议是修改它。 @spending.update(spending_params) returns 更新成功则为真,失败则为假。

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