【问题标题】:How to use devise current_user in Active Model Serializers如何在活动模型序列化器中使用设计 current_user
【发布时间】:2017-12-14 09:12:02
【问题描述】:

我在 rails5 中使用 Active Model Serializer 0.10.7

我想知道如何在序列化程序中访问设计 current_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

【问题讨论】:

  • 我可以在 Book 控制器中访问 c​​urrent_user。但它在序列化程序中为零......

标签: ruby-on-rails devise active-model-serializers


【解决方案1】:

Devise 不会将 current_user 帮助器暴露给模型或序列化程序 - 您可以将值从控制器传递给模型,或者将其设置在某个存储中。

其他答案的一些例子:

https://stackoverflow.com/a/3742981/385532

https://stackoverflow.com/a/5545264/385532

【讨论】:

    【解决方案2】:

    在应用程序控制器中:

    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 
    

    【讨论】:

    • 谢谢,但不起作用...这对设计 current_user 有用吗?
    • 你的 gem 版本是什么?先生
    • NoMethodError - #:0x007fd24a06be58>: 的未定义方法 `user_for_serializer'
    • 对不起。我犯了错误。这是我的 gem 版本active_model_serializers (0.10.7)
    • 我正在使用相同的版本...'o'
    【解决方案3】:

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

    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 
    
    
    

    【讨论】:

      【解决方案4】:

      如果您使用的是 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
      

      【讨论】:

        【解决方案5】:

        当您想自己初始化序列化器而不是 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 
        

        【讨论】:

          【解决方案6】:

          似乎有一个错字,你有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 
          

          【讨论】:

          • 抱歉错误!!但这不是问题。
          • @OtaniShuzo 你可以像render json: {books: BookSerializer.new(current_user, root: false)}一样明确传递
          猜你喜欢
          • 2015-07-14
          • 2018-09-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-05
          • 2015-08-23
          • 2016-09-03
          相关资源
          最近更新 更多