【问题标题】:how to call action from model to controller in ruby on rails如何在 ruby​​ on rails 中从模型调用动作到控制器
【发布时间】:2018-02-13 10:20:38
【问题描述】:

我正在尝试从帖子模型中调用“检查”操作。

class Post < ApplicationRecord
     after_commit :testing
     def testing
         @id = "#{self.id}"
         puts @id
         checking # call action to controller 
     end
end

posts_controller.rb

def checking
  puts "not Working"
end

我正在尝试实现上述目标,但它没有被调用。

【问题讨论】:

  • 你应该从控制器调用模型函数,模型不应该知道控制器逻辑
  • 你这样做的原因是什么?解释更多真正要做的事情,因为看起来你只是迷路了。
  • 模型不应该知道控制器逻辑。也许您可以重构并设置从控制器到模型的一些变量,就像在 thread 中描述的那样
  • 您到底想要什么?为什么你需要调用控制器?

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


【解决方案1】:

您可以通过实例化控制器来做到这一点。

SomeController.new.some_action

但是它是Not Recommended,因为您的模型逻辑应该独立于您的控制器逻辑。你的模型应该遵循Single-responsibility Principle

一个类应该只有一个职责。

您可能需要一些用于控制器和模型或一些服务的通用逻辑!!!!

【讨论】:

    【解决方案2】:

    正如人们所说:模型不应该知道控制器。

    根据原因,

    1. 您可以在模型中定义checking,并从Controller 中为当前Post 调用此方法。
    2. 如果应该从Controller 设置某些内容并签入Model,您可以使用定义的方法here

    【讨论】:

      【解决方案3】:

      正如许多(或所有)其他人所说,您不应该从模型中调用控制器操作。如果您正在保存/销毁来自控制器的对象并且您想检查是否调用了提交,您可以在保存或销毁后在控制器中执行此操作。

      posts_controller.rb

      def create
        @post = current_user.posts.build(post_params)
        if @post.save
          checking
        end
      end
      
      def checking
        puts "Is is working"
      end
      

      如果这不是你想要的,因为你对提交回调特别感兴趣,你可以把代码改成这样:

      posts_controller.rb

      def create
        @post = current_user.posts.build(post_params)
        @post.save
        if @post.commmited?
          checking
        end
      end
      
      def checking
        puts "Is is working"
      end
      

      并为您的模型添加一些逻辑:

      class Post < ApplicationRecord
        attr_accessor :commit_performed
      
        #unset the commit_performed attribute on first callbacks
        before_destroy :unset_commit
        before_validation :unset_commit
      
        #set the commit_performed attribute after commit
        after_commit :set_commit
      
        def unset_commit
          @commit_performed = false
        end
      
        def set_commit
          @commit_performed = true
        end
      
        def commited?
          @commit_performed
        end
      end
      

      【讨论】:

        【解决方案4】:

        您不应该从模型中调用控制器操作。这不是调用控制器方法的方式。如果你想触发一个动作,它应该被写成视图表单或输入法的目标,或者通过另一个控制器方法本身的重定向。如果您真的希望触发此操作(如果您希望在将记录保存到侦听器 url 后收到消息),我建议使用诸如 HTTP::Net 之类的库或 HTTParty 之类的 gem 来触发对动作,带有它的 url 或 rails url_helper。也不建议这样做,和/或不是在 Rails 中操作事物的方式。

        【讨论】:

        • 他的案子有很多工作要做。他并不是真的需要宝石,他需要思考他真正想要做什么。
        • 谢谢你们。这对我更有帮助。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-14
        • 2012-05-01
        • 2011-01-26
        • 1970-01-01
        • 2016-09-26
        • 2011-04-01
        • 1970-01-01
        相关资源
        最近更新 更多