Rails初学者架构 - 不止一个带文件上传的模型

时间:2017-02-21 12:02:36

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

我正在学习rails,我正在努力找出构建我的应用程序的最佳方法。

我有两个型号

Jobs
Posts

这些是应用程序的独立部分,但每个部分都可以随每条记录上传许多文件

我想知道构建这个的最好方法,我...

1 - 将所有文件保存在一个表中..创建上传模型,然后通过has_many:through(或多态关联)关联每个类型

2 - 使用单独的表格 - 创建 JobUploads PostUploads 模型(我不打算在关注点之间共享文件)

我认为要么可行,我的主要困惑是控制器/路线

我会创建新的 UploadsController JobUploadsController & PostUploadsController 取决于我选择的方法,还是会向现有的帖子和作业控制器添加新操作?

我想上传作业图片的理想路线是 / jobs /:job_id / files / new ,这是正确的做法吗?

如果我制作新的控制器,我最终会使用 / job_files / new ,那么我假设我必须以某种方式传递作业对象。

对不起,如果对某些人来说有点明显

非常感谢!

(ps使用rails 5)

2 个答案:

答案 0 :(得分:0)

我认为这里最好的想法是决定使用gem上传文件。最受欢迎的是 paperclip gem carrierwave gem 。根据他们的文档,你可以上传。

//github.com/carrierwaveuploader/carrierwave

//github.com/thoughtbot/paperclip

如果使用carrierwave,您不需要创建控制器。您可以创建一个上传器并将其安装在您的模型中......

Gems是在rails中进行文件上传的最简单方法。 您实际上不需要创建上传控制器。您可以在帖子,作业中添加一列,让gem处理上传。详细信息可在上面的链接中找到

答案 1 :(得分:0)

你最好的镜头是创建一个多态关联,或者像你说的UploadsController。假设您正在上传图片。

class UploadedImage < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
end

class Job < ActiveRecord::Base
  has_many :images, as: : imageable
end

class Post < ActiveRecord::Base
  has_many :images, as: : imageable
end

请记住在routes.rb

中定义
concerns :imageable do
  resources :uploaded_images, shallow: true
end

resources :posts, concerns: [:imageable]
resources :jobs, concerns: [:imageable]

这将创建喜欢的路线 - &gt; / posts /:post_id / images,/ jobs /:job_id / images

然后你只需要在UploadedImagesController中获取类型。在那里,您可以加载可成像类型并将图像附加到其上。示例控制器看起来像

class UploadedImagesController < ApplicationController

    prepend_before_filter :load_imageable,  only: :create

    def create
      @image = @imageable.images.create(image_params)
      render json: @image.as_json
    end

    def update
      @image = UploadedImage.find(params[:id])
      @image.update(image_params)
      render json: @image.as_json
    end

    def destroy
      @image = UploadedImage.find(params[:id])
      @image.destroy!
      render json: @image.as_json
    end

    private

    def load_imageable
      params.keys.select { |k| k =~ /([a-z_]*)_id/ }.first
      @imageable = $1.camelcase.constantize.find(params["#{$1}_id"])
    end

    def image_params
      params.require(:image).permit(:file, :caption)
    end
end

使用多态关联将带来许多优势并允许大量代码重用,因为您意识到系统的许多当前和未来模型将充当可成像的。