最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Can you invoke Jbuilder to create a native Rails object instead of a rendered string? - Stack Overflow

programmeradmin3浏览0评论

My Rails app broadcasts a set of records via Action Cable,

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

I'm calling ApplicationController.render to ensure jbuilder is invoked (I'm adding custom fields in my models/index.json.jbuilder file).

All works fine EXCEPT that the broadcast argument is converted to a string, thus I need to call JSON.parse(data['models']) in order for the data to be used in the JavaScript handler.

Is there anything I can do on the Ruby side to avoid string-ifying my payload and then parsing it on the client side?

My Rails app broadcasts a set of records via Action Cable,

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

I'm calling ApplicationController.render to ensure jbuilder is invoked (I'm adding custom fields in my models/index.json.jbuilder file).

All works fine EXCEPT that the broadcast argument is converted to a string, thus I need to call JSON.parse(data['models']) in order for the data to be used in the JavaScript handler.

Is there anything I can do on the Ruby side to avoid string-ifying my payload and then parsing it on the client side?

Share Improve this question edited Aug 25, 2016 at 13:11 sambecker asked Aug 23, 2016 at 14:14 sambeckersambecker 1,1391 gold badge12 silver badges28 bronze badges 0
Add a ment  | 

3 Answers 3

Reset to default 6

You can use Jbuilder directly (i.e. without that parsing step) by passing in an external builder instance to the renderer, as in this code for example:

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

I use the following helpers to return JSON data on client side

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

and after that in channel

# 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

A mit form my pet-project which demonstrate how it works

https://github./DeployRB/Rails5App/mit/14485b2c3311e6bd25e6ce841f2f7ee3f83954ff

If you are using typical Rails scaffolding, you can do something like this (this example assumes @model is set to the model you want, as in a controller):

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

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论