Rails 5嵌套表单图像上传,缓存和查看

时间:2017-12-10 07:42:00

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

我有两个型号;产品和变化。变体形式嵌套在产品形式中。我还使用Shrine文件附件gem来处理上传。我的变体模型有一个名称和一个照片领域。当照片领域是我的产品模型的一部分时,它工作得很好;我可以上传,预览和删除。自从将其移动到嵌套部分后,我在我的照片字段中获得了各种undefined methods。但作为测试,我删除了嵌套部分中的所有内容,并仅添加了file_field <%= f.file_field :photo_one %>并将文件上传并保存到数据库中,因此我知道部分关联设置正确。

_form_html.erb

...

<h4>Variations</h4>
<div class="row">
  <%= f.fields_for :variations do |variation| %>
    <%= render 'variation_fields', :f => variation %>
  <% end %>
</div>

<div class="row">
  <div class="col-md-4">
      <%= link_to_add_association 'add variation', f, :variations, :class => "btn btn--sm" %>
  </div>
</div>

<div class="row">
  <div class="col-md-4">
      <%= submit_tag 'Submit', class: 'btn btn--sm' %>
  </div>
</div>   
...

_variation_field.html.erb

<div class="nested-fields">
    <div class="row">
        <div class="col-md-6">
            <div class="col-md-6">
                <%= f.label :name, 'Name' %>
                <%= f.text_field :name %>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="col-md-4">
            <%= f.label :photo_one, 'Photo One' %>
            <% if :photo_one.present? %>
                <div class="product-image">
                    <%= image_tag(@product.photo_one_url(:thumb)) %>
                    <div class="input-checkbox input-checkbox--switch">
                        <input name="product[remove_photo_one]" type="hidden" value="0">
                        <input id="checkbox-switch" type="checkbox" name="product[remove_photo_one]">
                        <label for="checkbox-switch"></label>
                    </div>
                    <span>Remove Image</span>
                </div>
            <% end %>
            <%= f.hidden_field :photo_one, value: @product.cached_photo_one_data %>
            <%= f.file_field :photo_one %>
        </div>
    </div>
</div>

model product.rb

class Product < ApplicationRecord
  include ImageUploader[:spec_sheet]

  has_many :categories
  has_many :variations, dependent: :destroy
  accepts_nested_attributes_for :variations, allow_destroy: true
  accepts_nested_attributes_for :categories, allow_destroy: true

model variation.rb

class Variation < ApplicationRecord
    include ImageUploader[:photo_one]

    belongs_to :product
end

products_controller.rb

...
def product_params
  params.require(:product).permit(
      ...
      variations_attributes: [
        :id, 
        :name, 
        :position, 
        :photo_one,
        :remove_photo_one,
        :_destroy
      ],
  )
end

enter image description here

1 个答案:

答案 0 :(得分:0)

  1. @product中是否products#action实例化了

    def action
        @product = Product.new(product_params)
    end
    
  2. @product作为本地变量传递给partial

    <%= render 'variation_fields', locals: { f: variation, product: @product %>
    

    然后在您的部分_variation_field.html.erb

    <%= image_tag(product.photo_one_url(:thumb)) %>
    
  3. 更新

    进入你的控制台并测试神殿

    # no file is attached
    photo.image #=> nil
    
    # the assigned file is cached to temporary storage and written to `image_data` column
    photo.image = File.open("waterfall.jpg")
    photo.image      #=> #<Shrine::UploadedFile @data={...}>
    photo.image_url  #=> "/uploads/cache/0sdfllasfi842.jpg"
    photo.image_data #=> '{"id":"0sdfllasfi842.jpg","storage":"cache","metadata":{...}}'
    
    # the cached file is promoted to permanent storage and saved to `image_data` column
    photo.save
    photo.image      #=> #<Shrine::UploadedFile @data={...}>
    photo.image_url  #=> "/uploads/store/l02kladf8jlda.jpg"
    photo.image_data #=> '{"id":"l02kladf8jlda.jpg","storage":"store","metadata":{...}}'
    
    # the attached file is deleted with the record
    photo.destroy
    photo.image.exists? #=> false
    

    阅读shrine文档并在控制台中测试方法。一旦你可以在那里运行它们,你就可以建立功能。另请阅读documentation