gpt4 book ai didi

ruby-on-rails-4 - ActiveModel::Serializer 是否需要显式渲染调用?

转载 作者:行者123 更新时间:2023-12-03 17:52:29 25 4
gpt4 key购买 nike

我知道在使用 View 模板(html、rabl)时,我不需要在我的 Controller 操作中进行显式渲染调用,因为默认情况下,Rails 使用与 Controller 操作名称相对应的名称来渲染模板。我喜欢这个概念(不关心在我的 Controller 代码中呈现),因此想知道在使用 ActiveModel::Serializers 时这是否也可能?

例如,这是来自生成的 Controller (Rails 4.1.0)的代码:

class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]

#other actions
# GET /products/1
# GET /products/1.json
def show
end
end

这是序列化程序:
class ProductSerializer < ActiveModel::Serializer
attributes :id, :name, :description, :url, :quantity, :price
end

点击/products/1.json,我预计会发生两件事:
  • 要省略的序列化程序中未列出的字段,
  • 要封装在“产品”顶级字段中的整个 JSON 对象。

  • 但是,这不会发生,整个序列化程序将被忽略。但是,如果我将 Show 方法修改为以下内容:
    # GET /products/1
    # GET /products/1.json
    def show
    @product = Product.find(params[:id])
    respond_to do |format|
    format.html
    format.json { render json: @product }
    end
    end

    现在一切都很好,但我失去了 before_action 过滤器的好处(在我看来,我有一些多余的代码)。

    这真的应该怎么做?

    最佳答案

    没有明确的 renderrespond_withrespond_to Rails 会寻找匹配的模板。如果该模板不存在,Rails 会抛出错误。

    但是,您可以创建自己的解析器来绕过它。例如,假设您创建了 app\models\serialize_resolver.rb并将其放入其中:

    class SerializeResolver < ActionView::Resolver
    protected
    def find_templates(name, prefix, partial, details)
    if details[:formats].to_a.include?(:json) && prefix !~ /layout/
    instance = prefix.to_s.singularize
    source = "<%= @#{instance}.active_model_serializer.new(@#{instance}).to_json.html_safe %>"
    identifier = "SerializeResolver - #{prefix} - #{name}"
    handler = ActionView::Template.registered_template_handler(:erb)
    details = {
    format: Mime[:json],
    updated_at: Date.today,
    virtual_path: "/#{normalize_path(name, prefix)}"
    }
    [ActionView::Template.new(source, identifier, handler, details)]
    else
    []
    end
    end

    def normalize_path(name, prefix)
    prefix.present? ? "#{prefix}/#{name}" : name
    end
    end

    然后,在您的应用程序 Controller (或单个 Controller )中:
      append_view_path ::SerializeResolver.new

    有了这个,你应该能够做你想做的。如果是json请求,它会创建一个内容正确的erb模板并返回。

    限制:
  • 这有点笨拙,因为它依赖于不需要的 erb。如果我有时间,我将创建一个简单的模板处理程序。然后我们可以在没有 erb 的情况下调用它。
  • 这确实消除了默认 json回复。
  • 它依赖于 Controller 名称来查找实例变量( /posts 被转换为 @post 。)
  • 我只测试了一点。逻辑可能更聪明。

  • 笔记:
  • 如果存在模板,则将首先使用它。这允许您覆盖此行为。
  • 你不能简单地创建一个新的渲染器并注册它,因为默认进程不会命中它。如果未找到模板,则会出现错误。如果找到该文件,则直接调用模板处理程序。
  • 关于ruby-on-rails-4 - ActiveModel::Serializer 是否需要显式渲染调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17594572/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com