【问题标题】:Carrierwave upload works in Rails 4.x but not Rails 5Carrierwave 上传适用于 Rails 4.x 但不适用于 Rails 5
【发布时间】:2016-06-18 20:47:21
【问题描述】:

我已将代码制成一个虚拟测试站点以进行验证。此代码在使用 Rails (4.2.5.1) 时完全按照预期工作,但在使用 Rails (5.0) 时失败。我不明白实际问题出在哪里。

我的具体错误是Attachment article must exist,它以某种方式告诉我我没有将文章实例传递给它,但我只是无法弄清楚为什么它会起作用,就像在 Rails 4.x 实例中一样,但不是在Rails 5 beta 并认为它一定是我在其他地方没见过的东西。希望有人知道。

我有一个附件模型:

class Attachment < ApplicationRecord
  belongs_to :article
  mount_uploader :file, AttachmentUploader
end

我有一个文章模型:

class Article < ApplicationRecord  
  has_many :attachments, dependent: :destroy
  accepts_nested_attributes_for :attachments, reject_if: :all_blank
end

我有一个文章控制器:

class ArticlesController < ApplicationController
  before_action :set_article, only: [:show, :edit, :update, :destroy]

  # GET /articles/new
  def new
    @article = Article.new
    @article.attachments.build
  end

  def create
    @article = Article.new(article_params)

     respond_to do |format|
     if @article.save
        format.html { redirect_to @article, notice: 'Article was successfully created.' }
        format.json { render :show, status: :created, location: @article }
  else
        format.html { render :new }
        format.json { render json: @article.errors, status: :unprocessable_entity }
      end
   end
  end

private
  # Use callbacks to share common setup or constraints between actions.
  def set_article
    @article = Article.find(params[:id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def article_params
    params.require(:article).permit(:name, :content, attachments_attributes: [:file, :file_cache])
   end
end

我的表格如您所愿。我的文章形式:

<%= form_for(article) do |f| %>
  <% if article.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(article.errors.count, "error") %> prohibited this    article from being saved:</h2>

  <ul>
  <% article.errors.full_messages.each do |message| %>
    <li><%= message %></li>
  <% end %>
  </ul>
  </div>
 <% end %>

<div class="field">
  <%= f.label :name %>
  <%= f.text_field :name %>
</div>

<div class="field">
  <%= f.label :content %>
  <%= f.text_area :content %>
</div>

<div id="attachments">
  <h3>Attachments</h3>
  <%= render partial: "attachments/form", locals: { f: f, index: 0 } %>
</div>

<div class="actions">
  <%= f.submit %>
</div>

<% end %>

还有我的部分附件:

<%= f.fields_for :attachments, child_index: index do |ff| %>
  <%= ff.file_field :file, as: :file, label: "File ##{index += 1}" %>
  <%= ff.hidden_field :file_cache %>
<% end %>

【问题讨论】:

    标签: ruby-on-rails carrierwave


    【解决方案1】:

    在ArticlesController 中,对于new 和create,您将Article 对象分配给@article 变量。但在您的表单中,您使用的是article,而不是@article。看看更新变量是否能解决问题。

    将Article 模型更新为以下内容:

    class Attachment < ApplicationRecord
      belongs_to :article, optional: true
      mount_uploader :file, AttachmentUploader
    end
    

    【讨论】:

    • 刚试过。同样的问题。我以前也试过:)。
    • 请发布完整的堆栈跟踪。
    • 我可以访问跟踪不是错误。这是一个很好的干净错误,表明我需要分配一篇文章。 1 错误禁止保存这篇文章:附件文章必须存在如果我可以从处理的错误中获取堆栈跟踪,我不知道如何。
    • Rails 5 引入了对 belongs_to 关联的检查,并期望 belongs_to 另一侧的对象应该存在。这可能就是它失败的原因。我在答案中添加了更新的Attachment 模型。调整你的模型,看看它是否有效。
    • 效果很好。我真的需要阅读——并理解——发行说明,因为这让我发疯了。谢谢。
    【解决方案2】:

    按照 The Rails 4 Way 中的建议,改用decent_exposure gem,这样您就可以将实例变量排除在视图之外,并从控制器中移除额外的查找操作。

    https://github.com/hashrocket/decent_exposure

    class ArticlesController < ApplicationController
    
      expose(:article, params: :article_params)
      expose(:attachment, ancestor: :article)
    
      def create
        if article.save
          format.html { redirect_to article, notice: 'Article was successfully created.' }
          format.json { render :show, status: :created, location: article }
        else
          format.html { render :new }
          format.json { render json: article.errors, status: :unprocessable_entity }
        end
      end
    
      private
    
      def article_params
        params.require(:article).permit(:name, :content, attachments_attributes: [:file, :file_cache])
      end
    end
    

    在此示例中,new 方法被消除,因为 Decent Exposure 负责查找操作。

    【讨论】:

    • 很高兴看到这一点,但我不确定它如何帮助解决我遇到的这个特殊问题,除非我遗漏了什么。
    猜你喜欢
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-10
    • 2014-02-26
    • 2014-12-03
    • 1970-01-01
    相关资源
    最近更新 更多