【问题标题】:How would you remotely append new objects when the local variable is in the partial?当局部变量位于局部变量中时,您将如何远程附加新对象?
【发布时间】:2015-10-20 16:45:50
【问题描述】:

在我的对话索引页面中,我可以单击其中一个对话并远程显示该对话的消息。当消息出现时,有一个表单可以在两个用户之间的同一对话中发送另一条消息。以下是我的设置方式:

对话/index.html.haml

- @conversations.each do |conversation|
  = link_to conversation_messages_path(conversation), remote: true do
    = conversation.topic
.col-lg-12
  #messages-index 

消息/_message.html.haml

- @messages.each do |message|
  = message.body
= render 'messages/form'

消息/_form.html.haml

= form_for [@conversation, @message], remote: true do |f|
  = f.text_area :body
  = f.submit "Send"

消息/_index.js.erb

$('#messages-index').empty().append('<%= j render @messages %>')

conversations_controller.rb

class ConversationsController < InheritedResources::Base

  def index
    @conversations = Conversation.all
  end
end

messages_controller.rb

class MessagesController < InheritedResources::Base

    def index
        @conversation = Conversation.find(params[:conversation_id])
        @messages = @conversation.messages
        @message = current_user.messages.build

      respond_to do |format|
        format.js
      end
    end

  def create
    @message = current_user.messages.build(message_params)
    respond_to do |format|
      if @message.save
        format.js
      else
        format.js 
      end
    end
  end

end

我的问题是当我尝试发送消息并将新消息发布到对话中时,如下所示:

消息/_create.js.erb

$('#messages-index').replaceWith('<%= j render partial: "message", locals: {message: @message} %>');

这不起作用,因为它会发送 500 内部错误:

Started POST "/conversations/6/messages" for 127.0.0.1 at 2015-10-19 04:37:34 -0700
Processing by MessagesController#create as JS
  Parameters: {"utf8"=>"✓", "message"=>{"body"=>"dfdfd"}, "commit"=>"Send", "conversation_id"=>"6"}
  User Load (0.5ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1  ORDER BY "users"."id" ASC LIMIT 1  [["id", 4]]
   (0.2ms)  BEGIN
  SQL (15.2ms)  INSERT INTO "messages" ("body", "user_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"  [["body", "dfdfd"], ["user_id", 4], ["created_at", "2015-10-19 11:37:34.866111"], ["updated_at", "2015-10-19 11:37:34.866111"]]
   (47.8ms)  COMMIT
  Rendered messages/_message.html.haml (5.7ms)
  Rendered messages/create.js.erb (7.8ms)
Completed 500 Internal Server Error in 88ms (ActiveRecord: 63.6ms)

NoMethodError - undefined method `each' for nil:NilClass:
  app/views/messages/_message.html.haml:1:in `_app_views_messages__message_html_haml___2837667999247155781_70076471170800'
  actionview (4.2.3) lib/action_view/template.rb:145:in `block in render'
  activesupport (4.2.3) lib/active_support/notifications.rb:166:in `instrument'
  actionview (4.2.3) lib/action_view/template.rb:333:in `instrument'
  actionview (4.2.3) lib/action_view/template.rb:143:in `render'
........

那么我怎样才能以正确的方式附加它,以免出现each 错误?

更新

所以我想我必须如何让@messages 超出部分范围。现在是怎么做到的?这就是我的目标:

#messages-index
  - @messages.each do |message|
    = render message

更新 2

所以我成功解决了接收nileach的消息的问题。我必须做的是将conversation_id 分配给消息,因为它没有发生,但它仍然没有正确附加。我开始认为你不能这样设置。

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4


    【解决方案1】:

    你像这样渲染局部:

    1. render partial: "message", locals: {message: @message}
    2. render @messages

    但在部分_message.html.haml 中,您使用变量@messages。按照 Rails 约定,您应该在 `_message.html.haml' 中使用 @message

    请注意,放置= render 'messages/form' 并不是一件好事,因为这个部分是针对单个消息呈现的。


    更新

    这就是我的意思:

    对话/index.html.haml

    - @conversations.each do |conversation|
      = link_to conversation_messages_path(conversation), remote: true do
        = conversation.topic
    .col-lg-12
      #messages-index
    .col-lg-12
      #new-message-form
    

    消息/_message.html.haml

      = @message.body
    

    消息/_form.html.haml

    = form_tag conversation_messages_path(@conversation), remote: true do
      = text_area_tag :body
      = submit_tag "Send"
    

    消息/_index.js.erb

    # Render '_message' partial for each message from @messages
    $('#messages-index').empty().append('<%= j render @messages %>')
    
    # Render '_form' partial for new message for @conversation
    $('#new-message-form').empty().append('<%= j render partial: "form", locals: { conversation: @conversation }) %>')
    

    【讨论】:

    • 是的,我知道?将其更改为 message: @messages 并没有这样做,也没有任何其他变化。
    • 我的意思是在部分内部你应该使用@message(而不是@messages
    • 但是我已经在表单中使用了@message?还有其他方法吗?
    • 这是一个 Rails 约定,我不建议您违反约定。检查 rails docs 的部分内容。
    • @JohnHuntington,检查我关于部分的更新。至于控制器:message_params 从何而来?您只需将其配置为包含“conversation_id”
    【解决方案2】:

    当您的@messagesnil 时,就会出现错误。只需在您的app/views/messages/_message.html.haml 中添加一个条件即可检查@messages.nil? 是否存在

    【讨论】:

    • 对不起,我不太明白?
    • 您遇到了undefined method each for nil:NilClass 中出现的错误app/views/messages/_message.html.haml。这发生在没有消息时,即对象 @messages 为空 (nil)。这就是为什么您需要有一个案例来检查对象是否为空,在这种情况下呈现其他内容。
    • 当我执行if @messages.nil? 而不是else 渲染@messages 时,我仍然遇到同样的错误。
    • 你在打电话给each之前提出这个条件了吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-24
    相关资源
    最近更新 更多