简体   繁体   English

如何在js资产文件中使用ruby? (未定义的方法“ body”)

[英]how to use ruby in a js assets file? (undefined method 'body')

I'm following this tutorial and having a problem where using ruby in an ActionCable file causes an undefined method 'body' error. 我正在学习本教程 ,但遇到一个问题,即在ActionCable文件中使用ruby会导致undefined method 'body'错误。 How can I use ruby in this file? 如何在此文件中使用ruby? I want the data that's submitted over Action Cable to be properly formatted when it is appended, and I cannot do that with plain js. 我希望通过Action Cable提交的数据在添加时正确格式化,而我无法使用普通js做到这一点。 This is my app/assets/js/channels/messages.js.erb file: 这是我的app/assets/js/channels/messages.js.erb文件:

App.messages = App.cable.subscriptions.create('MessagesChannel', {
 received: function(data) {
  $("#response").val("");
  $('#messages').append(this.render_message(data));
  $("#conversation-main").scrollTop($("#conversation-main")[0].scrollHeight);
 },

 render_message: function(data) {
  return "<div class='message'><div><strong>" + data.user + ":</strong> <%= simple_format(@message.body) %></div><div class='date'><%= readable_datetime(@message.created_at) %></div></div>"
 }
});

I can't do simple_format(data.body) since that variable is js. 由于该变量是js,因此我无法执行simple_format(data.body) Here's the #create action in my messages controller: 这是我的消息控制器中的#create动作:

def create
    @message = @conversation.messages.new(message_params)
    @message.user = current_user

    respond_to do |format|
        if @message.save
            ActionCable.server.broadcast 'messages',
                body: @message.body,
                user: @message.user.username,
                time: @message.created_at
            head :ok
        end
    end
end

I have @message defined in the action, and it should be passed onto the js.erb file. 我在动作中定义了@message ,它应该传递到js.erb文件中。 But it's not. 但事实并非如此。 Why? 为什么?

Your messages.js.erb is in assets folder and ERB will run only once at assets compilation time. 您的messages.js.erb位于assets文件夹中,并且ERB在资产编译时仅运行一次。

Easier is to format before broadcasting while still in ruby controller context: 更容易的是仍在红宝石控制器环境中进行广播之前进行格式化:

ActionCable.server.broadcast 'messages',
            body: helpers.simple_format(@message.body),
            user: @message.user.username,
            time: @message.created_at

When you have Ruby code that you want to run inside any of your .erb files, you must use the <% ... %> or <%= ... %> notation surrounding the Ruby text. 当您要在任何.erb文件中运行Ruby代码时,必须在Ruby文本周围使用<% ... %><%= ... %>表示法。 The = in <%= ... %> is for outputting the code. =<%= ... %>是用于输出的代码。

https://guides.rubyonrails.org/layouts_and_rendering.html https://guides.rubyonrails.org/layouts_and_rendering.html

If you want data to be present here, it'll have to be an instance variable like @data that's assigned in the controller in order to be present when the view gets rendered. 如果要在此处显示data ,则必须是在控制器中分配的实例变量(如@data ,以便在呈现视图时显示。

From there you can do anything you want in "Ruby mode" engaged using: 在这里,您可以使用以下方法在“ Ruby模式”下进行任何操作:

render_message: function(data) {
  return "<div class='message'><div><strong><%= @data.user %>:</strong> <%= simple_format(@data.body) %></div><div class='date'><%= readable_datetime(@data.time) %></div></div>"
}

Or something approximately like that. 或类似的东西。

Remember that ERB substitutions are applied once and only once before the content is forwarded to the client for processing. 请记住, 将内容转发给客户端进行处理之前 ,一次且仅应用了一次ERB替换。 There's no way to run Ruby after the output is rendered. 呈现输出后,无法运行Ruby。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM