ruby-on-rails 如何在活动模型序列化程序中使用device current_user

zpf6vheq  于 2023-03-09  发布在  Ruby
关注(0)|答案(7)|浏览(170)

我在rails 5中使用Active Model串行器0.10.7
我想知道如何在序列化器中访问deviescurrent_user。
默认情况下,current_user应该设置为作用域。
根据文件
https://github.com/rails-api/active_model_serializers/blob/0-10-stable/docs/general/serializers.md#controller-authorization-context
但我的代码不太好用。
有人知道这事吗?

class BookSerializer < ActiveModel::Serializer

  attributes :id, :title, :url, :image, :is_reviewed

  def is_reviewed
    object.reviews.pluck(:user_id).include?(current_user.id)
  end
end

和Book控制器是这样的。

class BooksController < ApplicationController
  def index
    @books = Book.order(created_at: :desc).page(params[:page])
    respond_to do |format|
      format.html
      format.json {render json: @books, each_serializer: BookSerializer}
    end
  end
end
2ekbmq32

2ekbmq321#

当在控制器中示例化一个作用域时,可以将其传递给序列化程序(或其他地方)。我很欣赏这是针对单个对象而不是对象数组的:

BookSerializer.new(book, scope: current_user)

然后在Book Serializer中可以执行以下操作:

class BookSerializer < ActiveModel::Serializer

  attributes :id, :title, :url, :image, :is_reviewed

  private

  def is_reviewed
    object.reviews.pluck(:user_id).include?(current_user.id)
  end

  def current_user
    scope
  end
end
irtuqstp

irtuqstp2#

Devise不向模型或序列化程序公开current_user帮助器--您可以将值从控制器传递给模型,或者在某个存储器中设置它。
其他答案中的一些示例:
https://stackoverflow.com/a/3742981/385532
https://stackoverflow.com/a/5545264/385532

6mzjoqzu

6mzjoqzu3#

在应用程序控制器中:

class ApplicationController < ActionController::Base
  ...
  serialization_scope :view_context

end

在串行器中:

class BookSerializer < ActiveModel::Serializer

  attributes :id, :title, :url, :image, :is_reviewed

  def is_reviewed
    user = scope.current_user
    ...
  end
end
u0njafvf

u0njafvf4#

如果您使用active_model_serializers gem,那么它是直接的。
在序列化器中,只需使用关键字scope
例如:-

class EventSerializer < ApplicationSerializer
  attributes(
    :id,
    :last_date,
    :total_participant,
    :participated
  )

  def participated
    object.participants.pluck(:user_id).include?(scope.id)
  end
end
ckx4rj1h

ckx4rj1h5#

当你想自己初始化序列化器而不是render json: book时,你也可以从控制器传递视图上下文到序列化器。

# controller
BookSerializer.new(book, scope: view_context)

# serializer
class BookSerializer < ActiveModel::Serializer

  attributes :id, :title, :url, :image, :is_reviewed

  private

  def is_reviewed
    object.reviews.pluck(:user_id).include?(scope.current_user.id)
  end

end
5us2dqdw

5us2dqdw6#

我已经尝试过使用其他人建议的作用域解决方案,但是发现它不容易测试。我找到的一个替代方案是只将current_user传递给序列化器。所以你的控制器看起来像;

class BooksController < ApplicationController
  def index
    @books = Book.order(created_at: :desc).page(params[:page])
    respond_to do |format|
      format.html
      format.json {render json: @books, each_serializer: BookSerializer, user: current_user}
    end
  end
end

在你的序列化器中你会这样做

class BookSerializer < ActiveModel::Serializer
  attributes :id, :title, :url, :image, :is_reviewed

  def is_reviewed
    object.reviews.pluck(:user_id).include?(instance_options[:user].id)
  end
end

您可以在调用此序列化程序的任何地方定义用户,也可以执行&.z或检查它是否存在于序列化程序中,以便在未定义用户时不会出现错误

z0qdvdin

z0qdvdin7#

看起来有一个打字错误,您有is_reviewed,并且您定义了方法has_reviewed,因此它应该是这样的

class BookSerializer < ActiveModel::Serializer

  attributes :id, :title, :url, :image, :is_reviewed

  def is_reviewed
    object.reviews.pluck(:user_id).include?(current_user.id)
  end
end

相关问题