更新使用活动存储的用户记录不起作用

时间:2019-09-14 00:55:15

标签: ruby-on-rails ruby rails-api rails-activestorage

我正在练习使用Rails active_storage。因此,我创建了一个只有一个模型的应用程序-UserUser有两个主要的数据库列-usernameprofile_pic。然后通过active_storage进行has_many_attached :avatars。我要实现的功能是,我想将用户记录的before_validation分配为附加的第一个头像(用户在注册时可以上传许多图像)作为profile_pic。这是完整的模型

class User < ApplicationRecord
  include Rails.application.routes.url_helpers

  has_many_attached :avatars
  validates :username, presence: true
  before_validation :assign_profile_pic

  def change_profile_pic
    self.profile_pic = rails_blob_path(avatars.last, only_path: true)

    save
  end

  private

  def assign_profile_pic
    self.profile_pic = rails_blob_path(avatars.first, only_path: true)
  end
end

这是用户控制器

class V1::UsersController < ApplicationController
  # include Rails.application.routes.url_helpers

  def show
    user = User.find_by(username: params[:username])

    if user.present?
      render json: success_json(user), status: :ok
    else
      head :not_found
    end
  end

  def create
    user = User.new(user_params)
    if user.save
      render json: success_json(user), status: :created
    else
      render json: error_json(user), status: :unprocessable_entity
    end
  end

  def update
    user = User.find_by(username: params[:username])
    if user.update(user_params)
      user.change_profile_pic

      render json: success_json(user), status: :accepted
    else
      render json: error_json(user), status: :unprocessable_entity
    end
  end

  def avatar
    user = User.find_by(username: params[:user_username])

    if user&.avatars&.attached?
      redirect_to rails_blob_url(user.avatars[params[:id].to_i])
    else
      head :not_found
    end
  end

  private

  def user_params
    params.require(:user).permit(:username, avatars: [])
  end

  def success_json(user)
    {
      user: {
        id: user.id,
        username: user.username
      }
    }
  end

  def error_json(user)
    { errors: user.errors.full_messages }
  end
end

创建用户不是问题。它按预期工作,在创建时自动将user.avatars.first分配为user.profile_pic。问题发生在update部分。您看到成功更新后(在change_profile_pic中,我正在调用users_controller用户方法。问题是user.profile_pic永远不会更新。我已经调试了很多次,user_params并没有错。我想念什么?

1 个答案:

答案 0 :(得分:0)

before_validation每次在before_save之前运行。您只需设置一次,然后再设置一次。在此查看订单:https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html

如果仅更改个人资料照片,请避免使用assign_profile_pic进行验证。一种干净的方法是使用ActiveModel::AttributeMethods

class User < ApplicationRecord
  include Rails.application.routes.url_helpers

  has_many_attached :avatars
  validates :username, presence: true
  before_validation :assign_profile_pic, unless: :changing_profile_pic?
  attribute :changing_profile_pic, :boolean, default: false 

  def change_profile_pic
    self.profile_pic = rails_blob_path(avatars.last, only_path: true)
    self.changing_profile_pic = true 
    save
  end

  private

  def assign_profile_pic
    self.profile_pic = rails_blob_path(avatars.first, only_path: true)
  end
end