Rails4:如何在DB中为嵌套模型仅存储缩略图?

时间:2014-09-24 03:16:03

标签: ruby-on-rails ruby-on-rails-4 carrierwave

我只想将缩略图图像存储在数据库中作为二进制文件 到目前为止,我使用carrierwave将图像存储在文件系统中。它会保存原始文件和拇指。

如何更改源以仅在数据库中存储缩略图?
我使用关联。 article有很多photo

\ uploders \ image_uploder.rb

class ImageUploader < CarrierWave::Uploader::Base
.
.
  include CarrierWave::RMagick
  storage :file
  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end
.
.
end

文章表

sqlite> .schema articles
CREATE TABLE "articles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "content" varchar(255),"user_id" integer, "created_at" datetime, "updated_at" datetime, "category_id" integer);

照片表

sqlite> .schema photos
CREATE TABLE "photos" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "article_id" integer,"image" varchar(255), "created_at" datetime, "updated_at" datetime, "bin_image" blob); #prepare bin_image for saving image as binary 

\模型\ article.rb

class Article < ActiveRecord::Base
    belongs_to :user
.
.
    has_many :photos, dependent: :destroy
    accepts_nested_attributes_for :photos, reject_if: proc { |attributes| attributes[:image].blank? }, allow_destroy: true
    validate :check_for_at_least_image
.
.
    def build_images
      (3 - self.photos.size).times {self.photos.build}
    end

    def check_for_at_least_image
      errors.add(:image, "select...") if photos.reject(&:marked_for_destruction?).size <= 0
    end
.
.
end

\模型\ photo.rb

class Photo < ActiveRecord::Base
    belongs_to :article
    mount_uploader :image, ImageUploader
end

\控制器\ articles_controller.rb

class ArticlesController < ApplicationController

  before_action :signed_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: [:update, :destroy]
.
.
  def new
    @article = Article.new
    @category  = Category.find(params[:category])
    @article.category_id = @category.id
    3.times { @article.photos.build }
  end

  def create
    @article = current_user.articles.build(article_params)
    if @article.save
      flash[:success] = "article created!"
      redirect_to current_user #root_url
    else
        @article.build_images
        render 'new'
    end
  end

  def edit
    @article = Article.find(params[:id])
    @article.build_images
  end

  def update
    @article = Article.find(params[:id])
    if @article.update_attributes(article_params)
      redirect_to current_user
    else
      render 'edit'
    end
  end
.
.
  private

    def article_params
      params.require(:article).permit(:content, :category_id, photos_attributes: [:id, :article_id, :image, :image_cache, :_destroy])
    end
.
.
end

\ views \ shared \ _article_form.html.erb

.
.
<%= form_for(@article) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.hidden_field :category_id %>
    <%= f.fields_for :photos do |p| %>
      <%= p.hidden_field :article_id %>
      <div class="photo">
      <% if p.object.image and p.object.image.file %>
        <%= image_tag p.object.image.thumb.url %>
        <%= p.hidden_field :image_cache if p.object.image_cache %>
        <label><%= p.check_box :_destroy %>&nbsp;delete</label>
      <% end %>
      <%= p.file_field :image %>
      </div>
    <% end %>
    <%= f.text_area :content, placeholder: "enter content..." %>
  </div>
  <%= f.submit class: "btn btn-large btn-primary" %>
<% end %>

1 个答案:

答案 0 :(得分:0)

Carrierwave本身并不支持在blob中存储文件。这些是可用的选项。 https://github.com/carrierwaveuploader/carrierwave/tree/master/lib/carrierwave/storage