【问题标题】:Ruby on Rails multiple images connected to one objectRuby on Rails 多个图像连接到一个对象
【发布时间】:2017-01-25 04:23:49
【问题描述】:

我一直在尝试创建一个可以获取多个模型的参数的表单。我有一个属于产品模型的照片模型,我想制作它,以便在创建新产品时还可以上传通过 id 链接到该产品的图像。

<%= form_for @product, html:{multipart:true} do |f| %>
  <div class="field">
    <%= f.label :price %>
    <%= f.text_field :price %>
  </div>
  <%=form_for @photo do |t| %>
  <%t.productID = f.id%>
  <div class="field">
   <%= t.label (:image) %>
    <%= t.file_field (:image) %>
  </div>
  <%end%>
  <div class="actions">
    <%= f.submit %>
  </div>
<%end%>
现在我正在使用回形针作为图像附件,并且照片模型接受图像作为参数。我以前用过回形针,但该产品只能连接一个图像。如果我使用上面的表单,我会得到“表单中的第一个参数不能包含 nil 或为空”错误,它指向 form_for @photo 的开始位置。我有两个控制器,它们使用常用的新建、创建、更新等方法。我已经将资源路由到产品和照片,但我对 Rails 还是很陌生,并不完全理解这些东西是如何工作的。

【问题讨论】:

    标签: ruby-on-rails ruby forms paperclip


    【解决方案1】:

    我认为这不是正确的方法&lt;%t.productID = f.id%&gt;。也许试试&lt;% t.text_field :productID, value = f.id, type = hidden %&gt; 或类似的东西?

    这里有一些表单助手的文档,所以你知道在 t.abcd 后面放什么

    http://apidock.com/rails/v3.2.3/ActionView/Helpers/FormHelper/form_for

    【讨论】:

      【解决方案2】:

      你得到了

      “表单中的第一个参数不能包含 nil 或为空”

      ..error 因为@photo 为nil,你需要在你的控制器@photo = Photo.new 中设置它。

      另外,表单标签内的表单标签是无效的 HTML。

      https://www.w3.org/TR/html5/forms.html#the-form-element

      表格

      内容模型:流式内容,但没有表单元素 后代。

      您想改用f.fields_for。在此处了解如何使用它here

      我有两个控制器,使用常用的新建、创建、 更新等。

      当你去一个路径时,你只会点击一个控制器和动作,比如/photos 只会点击照片控制器(在你的 routes.rb 中配置)。我认为这是你搞砸@photo 变量的地方。将两者设置在同一个控制器中,以便视图能够看到这两个变量。

      【讨论】:

        【解决方案3】:

        我认为您正在尝试做的是使用 fields_for 帮助器的嵌套表单的一个很好的应用程序。

        首先,您需要确保您的产品模型和照片模型具有正确的关联(一个产品可能有_many 张照片,而一张照片属于一个产品,对吧?)。然后,您将确保产品类“接受照片的嵌套属性”,这允许您从产品表单向照片模型添加属性。

        在 products.rb 中

        class Product
          has_many :photos
          accepts_nested_attributes_for :photos
        end
        

        在 photo.rb 中

        class Photo
          belongs_to :product
        end
        

        然后,您需要确保照片所需的任何属性都在您的产品参数中列入白名单。

        在 products_controller.rb 中

        private
        def product_params
          params.require(product).permit(:first_product_attribute, :second_produtc_attribute, photo_attributes: [:image])
        end
        

        最后,您将使用特殊帮助器 fields_for 创建表单

        在你看来

        <%= form_for @product, html:{multipart:true} do |f| %>
          <div class="field">
            <%= f.label :price %>
            <%= f.text_field :price %>
          </div>
          <%= f.fields_for :photo do |t| %>
            <div>
              <%= t.label :image %>
              <%= t.file_field :image, :multiple => true %>
            </div>
          <% end %>
          <div class="actions">
            <%= f.submit %>
          </div>
        <%end%>
        

        您还需要确保您实际上是在产品的创建操作中创建新照片对象:

        在 products_controller.rb 中

        def create
          @product = Product.new(product_params)
            if @product.save!
              params[:photo]['image'].each do |img|
                @photo = @product.photos.create!(:image => img)
              end
            flash[:success] = 'product saved!'
            redirect_to @product
          end
        end
        

        其中一些是基于我做同样事情的经验,但使用 Carrierwave 而不是 Paperclip,因此您的具体实现可能会有所不同。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-03
          • 1970-01-01
          • 1970-01-01
          • 2010-10-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多