如何在目录中组织我的控制器,但仍然可以获得REST的好处?

时间:2018-06-10 01:41:00

标签: ruby-on-rails rest controller routing ruby-on-rails-5

上下文&背景

我有一个名为Stock的资源,代表公司的股票。那种模式& schema看起来像这样:

# == Schema Information
#
# Table name: stocks
#
#  id         :bigint(8)        not null, primary key
#  ticker     :string
#  name       :string
#  price      :float
#  created_at :datetime         not null
#  updated_at :datetime         not null
#  jse_link   :string
#

class Stock < ApplicationRecord
  has_many :port_stocks
  validates :ticker, :price, presence: true
end

然后我有一个User模型和一个Portfolio模型。每个User has_one: portfolio

我还有一个PortStock模型,它基本上是每个userportfolio中拥有的每个股票的实例。即使系统有关于库存ABC(公司名称,股票代码,价格等)的信息,每个用户将以不同的价格购买该股票,并购买不同数量的每个股票的单位,以便每个用户对库存ABC的位置将不同....因此需要新模型 - PortStock

话虽如此,每个Portfolio has_many :port_stocks

问题

我的核心问题是试图找出如何模拟买卖PortStock,因为业务规则不同。

当用户购买PortStock时,这是直截了当的。他们只需选择他们想要购买的股票,输入单位数量,他们想要购买的价格等等。然后我们创建一个PortStock的新记录。

棘手的部分是卖PortStock。必须考虑以下事项:

  1. 用户必须拥有PortStock
  2. 用户最多只能卖出他们拥有的PortStock个单位。
  3. PortStock并不意味着只是删除&#39;以前bought PortStock。它涉及创建另一条记录。
  4. 此新sell记录与此股票的其他buy记录中的一个(或多个)相关。即说用户A拥有1,000单位ABC,并且他们想要卖出500单位的ABC,还剩下500单位(即原始的1,000单位需要修改为500)。
  5. 所以我很难对这个&amp;让我的控制器正确。

    这是我PortStock模型的样子:

    # == Schema Information
    #
    # Table name: port_stocks
    #
    #  id             :bigint(8)        not null, primary key
    #  portfolio_id   :integer
    #  stock_id       :integer
    #  volume         :integer
    #  purchase_price :float
    #  current_price  :float
    #  percent_change :float
    #  created_at     :datetime         not null
    #  updated_at     :datetime         not null
    #  current_value  :float
    #  dollar_change  :float
    #  total_spend    :float
    #  bought_on      :datetime
    #  action         :integer
    #  position       :integer          default("open")
    #
    
    class PortStock < ApplicationRecord
      belongs_to :portfolio
      belongs_to :stock
    
      enum action: [ :buy, :sell ]
      enum position: [ :open, :closed ]
    end
    

    为了简化所有内容,我试图在我的PortStock#Sell控制器中执行PortStock#BuyPortStock次操作,因此我尝试将所有内容放入app/controllers/port_stocks/ ,例如app/controllers/port_stocks/buy_controller.rbapp/controllers/port_stocks/sell_controller.rb

    在每个文件中,我创建了_form.html.erbnew.html.erbcreate.html.erb个文件,以利用REST。

    所以,在我的路线中,我这样做了:

      resources :port_stocks do
        scope module: 'port_stocks' do
          resources :buy
          resources :sell
        end
      end
    

    这会生成以下new路线:

    new_port_stock_buy_path GET /port_stocks/:port_stock_id/buy/new(.:format)   port_stocks/buy#new
    

    请注意网址中的:port_stock_id

    但这对我来说还不合适。这一切都让我感到非常困惑,并不觉得它布局得当。

1 个答案:

答案 0 :(得分:1)

您似乎没有将stocks资源用于命名空间以外的任何内容,因此我建议您这样做:

namespace :stocks do
  resources :buy
  resources :sell
end

在努力保持RESTful时,我不喜欢你的buysell资源,因为那些是动词而不是名词(资源是名词;然后你有RESTful动作或动词)。也许:buy_order。他们排队的型号是什么?在纪念这些控制器之前,可能值得多考虑一下。