ruby-on-rails – Ruby on Rails最佳实践 – 大型控制器与小型控制器

我需要一些关于 Ruby on Rails最佳实践的信息,特别是对于必须做很多事情的Controller,因此,一个简单的“show”动作现在就行了.我知道,它不是很好,我有特定的代码.

这是一个示例代码

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,我必须重新解析所有响应……).

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的误解造成的.

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

>一方面你有anemic model,因为RoR使用ORM实例的集合,而不是真正的模型层.原因在于Rails最初是为快速原型设计(生成抛弃代码)而创建的.原型设计正是活跃记录最擅长的.使用scaffolding,您可以轻松地从现有数据库生成活动记录结构.

但这会导致某些域业务逻辑泄漏到您的控制器中.
>另一方面,你有不存在的观点.由于目标是原型设计,Rails倾向于通过将视图合并到控制器中来摆脱实际上包含表示逻辑的视图.现在缺少的视图被简单模板取代,简称模板称为“视图”.

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

这两个因素的原因是,为什么我很想断言,RoR甚至不是MVC框架.结果模式实际上更接近Model-View-Presenter.虽然它已经简化到它开始突破Separation of Concerns的程度.

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...