这应该是一个单独的模型,模型和控制器,还是其他一些Ruby类?

时间:2017-07-20 08:43:20

标签: ruby-on-rails design-patterns model-view-controller

目前在我的应用中QuoteRequest has_one Quote belongs_to QuoteRequest。 QuoteRequest具有完整的MVC,即QuoteRequest#new视图使用户能够创建对象及其数据并将其持久保存到db中的QuoteRequest表。

我现在正在研究如何设计下一个阶段,应该是;

  • 创建QuoteRequest时,它应该启动应用程序爬网到外部站点
  • 抓取并抓取以使用QuoteRequest数据获取引用结果,将结果保存到应用程序的数据库。
  • 然后呈现该持久报价数据的视图。

作为一个新手我很难决定如何最好地设计和写这个。我相信我理解一般的MVC标准,即为用户提供V的C,V从用户那里捕获一些东西然后C拿出那些东西并将其发送到M以将其持久保存到数据库中。但是我不确定除了具有这种定义的MVC关系之外的任何东西是否适合Rails环境。

在创建QuoteRequest之后的下一个阶段,这个过程的一部分不需要视图,即一旦QuoteRequest数据持久存储到数据库,它就需要启动应用程序中的某些内容,目前{{1}虽然还没有写在Quote中的功能,但这一切都没有了  爬行,刮擦和保存,然后我们又回到需要一个视图来保存要删除的刮痕。

所以我想知道这个过程的'非视图要求'阶段应该既不是模型也不是控制器,而是某种类型的标准Ruby类。例如。流程如下(请原谅奇怪的'伪代码'!):

  • 成功Quote>> QuoteRequest.save>>在OtherClass.start_crawl>>保存为OtherClass.crawl_success(无视图)>> Quote.create视图>>完成。

任何人都可以帮我决定如何设计这个,我猜这很简单,模式。感谢

2 个答案:

答案 0 :(得分:1)

我试图使用你的"伪代码"并结合控制器和PORO(普通的旧Ruby对象),下面是一些针对你的案例的提示

class QuoteRequestsController < ApplicationController

  def new
    @quote_request = QuoteRequest.new
  end

  def create
    @quote_request = QuoteRequest.new(quote_request_params)
    if @quote_request.save
      flash[:success] = "QuoteRequest successful save"
      # contact other class
      @crawling_service = MyModuleService::Other.new(@quote_request) 
      @crawling_service.start_crawl
      if @crawling_service.crawl_result # if success
        # create your quote
        @quote = @quote_request.create_quote(arg1, arg2, etc)
        @quote.save
        # after save redirect_to quote show
        redirect_to quote_path(@quote)
      end
    else
      flash[:error] = @barang.errors.full_messages[0]
    end
  end
end

将PORO创建为rails中的服务

创建app / services文件夹,然后您可以创建一个文件 在此文件夹中,名称为my_module_service.rb

module MyModuleService
  attr_reader :crawl_result
  class Other
    def initialize(quote_request)
      @quote_request = quote_request
    end

    def start_crawl
      # your start crawl process
      if success
        crawl_result = true 
        # this for send message back whether success or not the crawling
      else
        crawl_result = false
      end


    end
  end
end

答案 1 :(得分:1)

当我看到它时,我觉得爬行应该是一个后台任务,所以它不会占用进程。

  • 在QuoteRequest模型中添加after_save(或者您也可以在控制器中调用它)
  • 创建一个空的Quote对象或许
  • 使用后台任务库,例如resquesidekiq
  • 编写执行爬网的工作人员(activejob)并使用结果更新上面的Quote对象。)
  • 引用视图应显示它在尚未抓取时处理。