【问题标题】:Ruby on Rails two create actions to two different controllers simultaneouslyRuby on Rails 两个同时为两个不同的控制器创建动作
【发布时间】:2012-04-08 08:40:41
【问题描述】:

我有一个线程控制器和消息控制器。

线程 has_many 消息

一旦用户点击发送,我将数据发送到线程控制器以创建线程。我想做到这一点

threads_controller.rb

def create
    ...
    if @thread.save
         #send data into messages_controller 
         #to create the corresponding table for a message with this thread_id

end

所以,如果第一个成功,基本上我会尝试一个接一个地做两个 POSTS。

我认为 redirect_to 是我应该使用的。是否可以使用 redirect_to 传递参数并从不同的控制器调用创建操作?

编辑: 我必须有一个线程(由于 Ryan 提到的原因,名称选择不好,但为了不让人们与底部的答案混淆,让我们保留它)模型和消息模型在这里。线程表只需要传入message_title即可。 Message 表包含 from_id(用户发送消息的 id)、to_id(用户接收消息的 id)和 message_content。我正在尝试以一种包含 message_title 和 message_content 的形式来完成所有这些工作。

我希望这有助于理解这个问题。

谢谢大家

【问题讨论】:

  • 这没有意义,给线程创建一条消息。
  • 后端不应依赖 HTTP 命令。如果您这样做,有人可以通过向您的应用发送发布请求来创建线程。这对你有意义吗?
  • 戴夫,我实际上正在尝试为我的应用程序在两个人之间创建一个私人消息传递解决方案,我认为可能有必要在后端这样做。如果这是一个每个人都可以发布的线程,我想我可以创建一条消息。
  • Castilho,我想我知道你在说什么,但这就是 rails 处理在后面创建动作的方式。所以我不确定如果我使用 rails 还能怎么做
  • 我不明白你在说什么;到目前为止,听起来你让这件事变得比实际更复杂。消息发给谁根本不重要,无论消息是在哪里创建的,您都使用相同的参数。

标签: ruby-on-rails ruby-on-rails-3 controller


【解决方案1】:

我认为您以错误的方式处理此问题。

首先:我真的希望你不要调用模型Thread,因为这会与Ruby 类Thread 冲突。如果是,请选择其他词

现在,“请把枪远离从你的脚上瞄准”消息让开......


您不应该调用MessagesController 来为控制器创建新消息。相反,您应该在新线程表单中使用嵌套属性:

<%= form_for @thread do |f| %>
  <%= f.fields_for :messages do |message| %>
    <%= render "messages/form", :message => message %>
  <% end %>
<% end %>

在您的DiscussionThread(我在这里假设它的名称)模型中,您将拥有这些行:

has_many :messages
accepts_nested_attributes_for :messages

您可能还需要将messages_attributes 添加到此模型中的attr_accessible 属性。

这告诉DiscussionThread 模型实例也可以接受messages 关联的属性。在您的 ThreadsController 中,该操作将保持不变。

有关嵌套属性的更多信息,我建议观看 Nested Forms #1Nested Forms #2 上的 Railscast。

【讨论】:

  • 嗨瑞恩,感谢您的建议。我没有意识到拥有一个模型 Thread 会是一个问题。我将使用不同的名称。
【解决方案2】:

如果我理解您的问题,您需要做的就是调用 Message 模型上的 create 方法并传入相关信息。所以在你的 if @thread.save 中有这样的东西:

Message.create(:item_1 => params[:item_1])

如果你不想走这条路,你可以使用嵌套资源,然后让 Rails 在你传递正确信息时自动创建新消息。

【讨论】:

  • 感谢乔希,这很有帮助。我不知道为什么我从来没有想过这个
【解决方案3】:

没有理由去另一个控制器。您可以在线程控制器中执行以下操作:

@thread.messages << Message.new(...)

或在消息控制器中执行此操作,这对我来说更有意义,因为您的用户正在创建带有线程创建作为副作用的消息。如果您正确发送thread_id,在params[:message][:thread_id] 中创建对象时将自动建立关联:

@message = Message.create(params[:message]) 

如果您需要一些其他逻辑来决定消息与哪个线程相关联,只需直接设置thread_id

@message.thread_id = current_thread.id # Or Thread.create(...) or whatever
@message.save

【讨论】:

    【解决方案4】:

    我将您的基本用例视为:

    • 创建新消息和线程
    • 在现有线程中创建新消息
    • 查看消息
    • 查看话题和所有相关消息

    我建议多对多关系: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_and_belongs_to_many

    # define has and belongs to many relationship
    
    class Message
      has_and_belongs_to_many :threads
    end
    
    class Thread
      has_and_belongs_to_many :messages
    end
    
    class MessageThread
      belongs_to :message
      belongs_to :thread
    end
    
    # use case: creating a new message and a new thread, showing message
    
    class MessagesController < ApplicationController
      def create
        @message = current_user.messages.create! :text => params[:text]
        @thread = @message.threads.create!
      end
    
      def show; @message = current_user.messages.find(params[:id); end;
    end
    
    # use case: creating a message in an existing thread
    
    def MessagesThreadsController < ApplicationController
      def create
        @thread = current_user.threads.find params[:id]
        @thread.messages.create! :text => params[:text]
      end
    end
    
    # use case: viewing all messages in a thread
    
    def ThreadsController < ApplicationController
      before_filter :set_thread
    
      def show
        @thread = current_user.threads.find params[:id]
        @messages = @thread.messages
      end
    end
    

    【讨论】:

    • 感谢 juwiley,您的意见帮助很大
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 1970-01-01
    • 1970-01-01
    • 2010-10-03
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    相关资源
    最近更新 更多