【问题标题】:How do I pass a parameter from my new method to my create method in Rails?如何将新方法中的参数传递给 Rails 中的 create 方法?
【发布时间】:2014-04-03 17:26:04
【问题描述】:

如果特定参数已传递给新方法,我需要在我的创建方法结束时调用一个方法。我试图在不向我正在创建的对象中添加新字段的情况下执行此操作,只是为了成为一个临时的“参数存储桶”。该参数不会在创建新对象时使用,而是在保存对象后调用的辅助方法中使用。

所以在代码中类似于...

def new
  @object = Object.new
  if params[:object_id]
    @object_trade = Object.find(params[:object_id])
  end
end

def create
  blah create blah
  if @object.save && @object_trade.present?
    call_method_here(@object_trade.id)
  end
end

不过,我不能把这些碎片拼凑起来。我觉得我错过了一些明显的东西。

对于它的价值,我可以传递对象或只是我需要做的参数。

感谢任何帮助。

【问题讨论】:

    标签: ruby-on-rails ruby


    【解决方案1】:

    Kirti Thorat rightly points out 为什么实例变量不起作用,但建议使用会话,这可能是错误的。

    如果用户使用object_id 导航到“新”页面,但从未提交表单怎么办?相反,他们点击后退按钮并再次请求“新”,这次没有object_id,因为他们改变了主意。但是,object_trace 仍然在会话中徘徊,应用程序错误地记住了原始的 object_id

    我相信 flash 也会遇到类似的问题。

    避免会话很容易

    以您的“新”操作呈现的形式呈现隐藏字段:

    = hidden_field_tag 'object_id', params[:object_id]
    

    然后,当您提交表单时,object_id 将被传递,并且可以作为params[:object_id] 用于创建操作。

    避免会话的其他原因

    • 更容易理解和调试:随着您的应用程序变得越来越复杂,您会发现如果请求中发生的错误每次在您运行相同的请求时都会发生,这会简单得多具有相同的参数。尝试修复无法可靠重现的错误并不有趣。
    • 无状态方法与有状态方法一样易于实施
    • 避免任何类型的会话存储的限制您的应用配置为使用:
      • 如果使用 cookie 存储,您最终会想要存储一些太大而无法放入 cookie 的内容。
      • 如果使用数据库存储,您有朝一日可能会遇到值在会话中无限期徘徊的问题。
      • 如果使用 memcache 存储,您将无法将您的应用扩展到多个 memcached 实例,并且在您需要重新启动 memcached(或它所在的服务器)时,您的应用也会中断。

    【讨论】:

    • 这些是令人信服的观点。无状态模型的出错空间肯定更小。谢谢你的澄清。
    【解决方案2】:

    重新定义你的方法如下:

    def new
      @object = Object.new
      if params[:object_id]
        session[:object_trade] = params[:object_id]
      end
    end
    
    def create
      blah create blah
      if @object.save && session[:object_trade].present?
         @object_trade = Object.find(session[:object_trade])
         call_method_here(@object_trade.id)
         session.delete(:object_trade)  ## Remove object_trade from the session
      end
    end
    

    每次调用动作时,都会加载一个单独的控制器实例。因此,您不会在create 操作中获得@object_trade。但是 session 将允许您在不同的操作之间共享数据。

    注意:

    从会话中删除object_trade 的原因,即session.delete(:object_trade) 是在给定时间每个会话只能执行一个new 操作。这样,antinome (in cmets) 提出的问题不会在 if 块的 create 操作中执行活动。如果 OP 想给用户一条消息,那么他可以在 else 部分添加一条 flash 消息,说明原因类似于 session key invalid..Please try again 并重定向到新表单。

    【讨论】:

    • 最好使用flash 而不是session。这样创建操作完成后会自动清除。
    • 正是我需要的。非常感谢。
    • 我实际上尝试过使用闪存,但无法通过它传递信息。也许我只是用错了。
    • @TyrelDenison 很高兴为您提供帮助。我还添加了session.delete(:object_trade),它将从会话中删除 object_trade
    • 如果用户在具有两个不同对象 ID 的两个浏览器选项卡中打开“新”操作,这将中断。此外,我发现当您尽可能保持操作无状态时,调试会要容易得多。 (有关无状态方法,请参阅我的答案。)
    猜你喜欢
    • 2013-01-25
    • 1970-01-01
    • 2011-11-24
    • 2011-10-17
    • 2017-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-18
    相关资源
    最近更新 更多