Ruby on Rails最佳实践-大控制器与小控制器 [英] Ruby on Rails Best practices - Big Controller vs Small Controller

查看:69
本文介绍了Ruby on Rails最佳实践-大控制器与小控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要一些有关Ruby on Rails中最佳实践的信息,尤其是对于必须要做很多事情的 Controller ,因此,一个简单的显示"操作现在最多.我知道这不是很好,并且其中包含特定的代码.

I need some informations for the best practices in Ruby on Rails, especially with Controller who have to do a lot of things, so, a simple "show" action is now up to lines. I know, it's not really good, and I have specific code in it.

以下是示例代码:

def show
    sound = Sound.find(params[:id])
    @xml_path = File.dirname(sound.file.path)
    s3 = AWS::S3.new(
        :access_key_id => 'XXX',
        :secret_access_key => 'XXX')
    @url = s3.buckets['dev'].objects[sound.file.path[1..-1]].url_for(:read, :expires => 10*60)

    if sound.id_job != 0 && sound.transcript_progress != 100
      @response = Savon.client("http://srap.php?wsdl").request(:avance) do
        soap.body = { 
         :Jeton => "abcdef",
         :ID_job => sound.id_job,
        }
      end
      @response = @response.to_hash
      @progress = @response[:avance][:avancement].to_s.split("#")[1]# ID_job received is formed like "OK#123", we keep "123"
      if @progress == "Termine"
         sound.transcript_progress = 100
      elsif @progress == "ERROR"
        flash.now[:alert] = "Oups, il semblerait que le fichier soit illisible, ou qu'il n'y ait rien a ecouter !"
      elsif @progress != "Queued"
        sound.transcript_progress  = @response[:avance_response][:avancement].to_s.split("#")[2].split("%")[0].to_i
      end
      sound.save
    end

    if sound.transcript_progress == 100 # If transcription finished
      # Get XML File URL on the FTP
      @xml_path = Savon.client("http://srap.php?wsdl").request(:donneResultat) do
      soap.body = { 
       :Jeton => "XXX",
       :FichierSon => sound.id_job
      }
      end

      # Parse XML Path URL on Kimsufi
      @xml_path = @xml_path.to_hash[:donne_resultat_transposition_response][:chemin_fichier].to_s.split("#")[2].to_s.split("/")[5]


      # Create local directory (/tmp/sounds) for XML Temp Save
      if ! File.directory?(Rails.root.to_s + '/tmp/sounds')
        Dir.mkdir(Rails.root.to_s + '/tmp/sounds')
      end
      # Get XML from FTP
      ftp=Net::FTP.new                                     
      ftp.connect("ftp.com", 21)                                                         
      ftp.login("XXX", "XXX")                
      if ftp.closed?
        flash.now[:alert] = "Oups, il semblerait qu'il y ait eu un problème ! Merci d'actualiser la page"
      else  
        ftp.passive = true
        ftp.chdir('results')
        ftp.getbinaryfile(@xml_path, Rails.root.to_s + '/tmp/sounds/' + @xml_path)
        ftp.close
      end

      # Send XML on S3
      s3 = AWS::S3.new(
        :access_key_id => 'XXX',
        :secret_access_key => 'XXX')
      @xml_new = (File.dirname(@sound.file.path) + '/' + File.basename(@xml_path))[1..-1]
      s3.buckets['dev'].objects[@xml_new].write(Pathname.new(Rails.root.to_s + '/tmp/sounds/' + @xml_path))
      @file = s3.buckets['dev'].objects[@xml_new].read()
    end


    # A lot of logic again, i've not did it yet

  end

如您所见,我这里有很多逻辑, 我必须检查转录是否结束, 如果没有,请更新progress_bar(@ sound.transcript_progress), 如果是,我首先必须连接到soap操作以获取XML路径,然后通过FTP获取XML,然后将其存储到Amazon S3(Shitty SOAP,我必须重新解析所有响应...).

As you can see, I have a lot of logic here, I have to check if the transcription is over, if not, update the progress_bar (@sound.transcript_progress), if yes, i first have to connect to a soap action to get the XML path, then get the XML via FTP, then stock it to the Amazon S3 (Shitty SOAP, i have to reparse all response...).

在我所有的动作控制器中,我必须连接S3/SOAP/FTP,而不是 以相同的顺序..所以我在想为每个人上一堂课,就像在 C ++,一种抽象.我想把事情做好,我不在乎(很多) 完成.但是,使用MVC的最佳实践是什么?我必须做一个 新文件夹类?"一个新的控制器?

In all my action controller, i have to connect on S3 / SOAP / FTP, not in the same order.. So i i'm thinking to do a class for each, like in C++, an abstraction. I want the stuff done, i don't care (a lot) how it's done. But what's the best practice with the MVC? I have to make a new folder "Class?" A new controller?

推荐答案

这更像是长篇评论,因为它解释了困境的根源,但没有提供解决方案.

This is more of a long-form comment, since it explains the origin of your dilemma, but provides no solutions.

问题实际上是由RoR流行的对MVC的误解引起的.

The problem actually is caused by misinterpretation of MVC, which RoR popularizes.

这是两个因素的组合,这些因素导致控制器内爆:

It is the combination of two factors, which are causing this implosion of controller:

  • 一方面,您拥有贫血模型,因为它不是真实模型RoR使用ORM实例的集合.这样做的原因是,Rails最初创建时是一个用于快速原型设计(生成一次性代码)的框架.原型制作正是主动记录最擅长的.使用脚手架,您可以轻松地从现有数据库生成活动记录结构.

  • On the one side you have anemic model, because, instead of real model layer, RoR uses collection of ORM instances. The reason for it is that Rails was originally created to be a framework for fast prototyping (generation of throw-away code). And prototyping is exactly what active record is best at. Using scaffolding, you can easily generate active record structures from existing databases.

但这会导致某些域业务逻辑在控制器中泄漏.

But this cause some of the domain business logic to leak in your controllers.

在另一侧,您没有该视图.由于目标是原型,Rails倾向于通过将视图合并到控制器中来消除视图,这些视图实际上可以包含表示逻辑.现在丢失的视图已被简单的模板所取代,这些模板被称为视图".

On the other side you have the non-existent view. Since the goal was prototyping, Rails favored getting rid of views, which can actually contain presentation logic, by merging them into the controllers. The, now missing, views were replace with simple templates, which are just called "views".

这会强制控制器包含表示逻辑.

This forces controllers to contain presentation logic.

这两个因素可能就是为什么我很想断言RoR甚至不是MVC框架的原因.结果模式实际上更接近模型-视图-演示器.尽管已简化到开始中断的地步,但关注的分离.

These two factors would be the reason, why I am tempted to assert, that RoR is not even MVC framework. The resulting pattern is actually closer to Model-View-Presenter. Though it has been simplified to the point at which it starts to break Separation of Concerns.

这篇关于Ruby on Rails最佳实践-大控制器与小控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆