你能调用Jbuilder来创建一个原生Rails对象而不是一个呈现的字符串吗?

Can you invoke Jbuilder to create a native Rails object instead of a rendered string?

本文关键字:一个 字符串 原生 Jbuilder 调用 创建 Rails 对象      更新时间:2023-09-26

我的Rails应用程序通过Action Cable广播一组记录,

ActionCable.server.broadcast 'model_channel', models: (ApplicationController.render 'models/index.json', assigns: { models: Model.all })

我正在调用ApplicationController.render以确保调用jbuilder(我在models/index.json.jbuilder文件中添加自定义字段)。

所有工作正常,除了broadcast参数被转换为字符串,因此我需要调用JSON.parse(data['models'])以便在JavaScript处理程序中使用数据。

我可以在Ruby端做些什么来避免字符串化我的有效负载,然后在客户端解析它?

您可以通过将外部构建器实例传递给呈现器来直接使用Jbuilder(即无需解析步骤),如下面的代码所示:

class ReservationChannel < ApplicationCable::Channel
  def subscribed
    reservation = Reservation.find(params[:reservation_id])
    stream_for reservation
  end
  def self.reservation_update(reservation)
    broadcast_to reservation, reservation_data_for_json(reservation)
  end
  private
  def self.reservation_data_for_json(reservation)
    Jbuilder.new do |json|
      ApplicationController.render(
        template: 'reservation/index.jbuilder',
        locals: { reservation: reservation, json: json }
      )
    end.attributes!
  end
end

我使用以下帮助程序在客户端返回JSON数据

module ChannelHelper
  def render_view(params)
    ApplicationController.render(params)
  end
  def render_json(params)
    JSON.parse render_view(params)
  end
  def broadcast channel, message
    ActionCable.server.broadcast channel, message
  end
end

和之后的通道

# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading.
class NotesChannel < ApplicationCable::Channel
  include ChannelHelper
  def subscribed
    stream_from "notes_channel"
  end
  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
  def random
    broadcast 'notes_channel', render_json(
      template: 'notes/ws_random',
      locals: { note: Note.random.first }
    )
  end
end

我的宠物项目的提交,演示它是如何工作的

https://github.com/DeployRB/Rails5App/commit/14485b2c3311e6bd25e6ce841f2f7ee3f83954ff

如果您正在使用典型的Rails脚手架,您可以这样做(本示例假设@model被设置为您想要的模型,就像在控制器中一样):

json = ApplicationController.render(partial: 'model/model.json', locals {model: @model}) JSON.parse(json)