创建父记录后创建空子记录(Rails 4)

时间:2014-07-24 19:11:19

标签: ruby-on-rails carrierwave nested-attributes

我有一个名为Images的模型,上面附有一个上传器(Carrierwave)。图像属于名为Listing的模型。创建列表后,我被重定向到图像索引页面上传文件( localhost:3000 / listings / 1 / images

但出于某种原因,每当我创建一个列表时,它就会同时创建。实际上没有图像存在,但它显示了我对每个图像的“删除”链接。

<span><%= link_to 'DELETE', listing_image_path(@listing, image.id), data: { confirm: 'Are you sure?' }, :method => :delete, :class => 'delete' %></span>

有任何帮助吗?感谢。

列表控制器

class ListingsController < ApplicationController
   before_action :set_listing, only: [:show, :edit, :update, :destroy]
   before_filter :authenticate_user!, :except => [:show, :index]

   def index
      @listings = Listing.order('created_at DESC')

      respond_to do |format|
         format.html
         format.json { render json: @listings }
      end
   end

   def show
   end

   def new
      @listing = Listing.new
      @listing.user = current_user
   end

   def edit
   end

   def create
      @listing = Listing.new(listing_params)
      @listing.user = current_user

      respond_to do |format|
         if @listing.save
            format.html { redirect_to listing_images_path(@listing), notice: 'Post was successfully created.' }
         else
            format.html { render action: 'new' }
            format.json { render json: @listing.errors, status: :unprocessable_entity }
         end
      end
   end

   def update
      respond_to do |format|
         if @listing.update(listing_params)
            flash[:notice] = 'Deal was successfully updated.'
            format.html { redirect_to @listing }
            format.json { head :no_content }
         else
            format.html { render action: 'edit' }
            format.json { render json: @listing.errors, status: :unprocessable_entity }
         end
      end
   end

   def destroy
      @listing.destroy

      respond_to do |format|
         format.html { redirect_to listings_url }
         format.json { head :no_content }
      end
   end

   private
      # Use callbacks to share common setup or constraints between actions.
      def set_listing
         @listing = Listing.friendly.find(params[:id])
      end

      # Never trust parameters from the scary internet, only allow the white list through.
      def listing_params
         params.require(:listing).permit(:id, :condition, :description, :nickname, :price, :size, :title, :user_id)
      end
end

列表表单

<%= form_for(@listing, :html => { :class => 'form', :multipart => true }) do |f| %>
   <% if @listing.errors.any? %>
      <div id="error_explanation">
         <h2><%= pluralize(@listing.errors.count, "error") %> prohibited this listing from being saved:</h2>

         <ul>
         <% @listing.errors.full_messages.each do |msg| %>
            <li><%= msg %></li>
         <% end %>
         </ul>
      </div>
   <% end %>

   <div>
      <%= f.label :title %>
      <%= f.text_field :title, :required => true %>
   </div>

   <div>
      <%= f.label :price %>
      <%= f.text_field :price %>
   </div>

   <div class="actions">
      <%= f.submit 'Submit', :class => 'buyNow' %>
   </div>
<% end %>

图像控制器

class ImagesController < ApplicationController
   before_action :set_image, only: [:show, :edit, :update, :destroy]
   before_filter :load_listing

   def index
      @images = @listing.images.load
      @image = @listing.images.new
   end

   def new
   end

   def edit
   end

   def create
      @image = @listing.images.new(image_params)

      respond_to do |format|
         if @image.save
            format.html { redirect_to :back, notice: 'Image was successfully created.' }
            format.json { head :no_content }
         else
            format.html { render action: 'new' }
            format.json { render json: @image.errors, status: :unprocessable_entity }
         end
      end
   end

   def update
      respond_to do |format|
         if @image.update(image_params)
            format.html { redirect_to (@image.listing), notice: 'Image was successfully updated.' }
            format.json { head :no_content }
         else
            format.html { render action: 'edit' }
            format.json { render json: @image.errors, status: :unprocessable_entity }
         end
      end
   end

   def destroy
      @image = @listing.images.find(params[:id])
      @image.destroy

      respond_to do |format|
         format.html { redirect_to :back }
         format.json { head :no_content }
      end
   end

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

      def load_listing
         @listing = Listing.find(params[:listing_id])
      end

      # Never trust parameters from the scary internet, only allow the white list through.
      def image_params
         params.require(:image).permit(:file, :listing_id)
      end
end

图片索引

<div>
    <%= form_for [@listing, @image], :html => { :class => 'uploadImages', :multipart => true } do |f| %>
       <%= f.hidden_field :listing_id %>

       <div>
          <%= f.label :file, 'Upload Images' %>
          <%= f.file_field :file, multiple: true, name: 'image[file]' %>
       </div>
    <% end %>
</div>

<div id="progress"></div>

<% if @images.present? %>
    <ul class="editGallery">
        <% @listing.images.each do |image| %>
            <li>
                <%= image_tag image.file_url(:list) if image.file? %>
                <span><%= link_to 'DELETE', listing_image_path(@listing, image.id), data: { confirm: 'Are you sure?' }, :method => :delete, :class => 'delete' %></span>
            </li>
        <% end %>
    </ul>
<% end %>

2 个答案:

答案 0 :(得分:0)

问题在于这一行:

@image = @listing.images.new

这正在为@listing构建一个新图像,所以当你调用@listing.images.each新图像包含在images数组中时。在为其构建删除链接之前,请检查图像是否已实际保存到数据库中。

<% @listing.images.each do |image| %>
  <% unless image.new_record? %>
    <li>
      <%= image_tag image.file_url(:list) if image.file? %>
      <span><%= link_to 'DELETE', listing_image_path(@listing, image.id), data: { confirm: 'Are you sure?' }, :method => :delete, :class => 'delete' %></span>
    </li>
  <% end %>
<% end %>

答案 1 :(得分:0)

看一下代码的这一部分:

<% if @images.present? %>
<ul class="editGallery">
    <% @listing.images.each do |image| %>
        <li>
            <%= image_tag image.file_url(:list) if image.file? %>
            <span><%= link_to 'DELETE', listing_image_path(@listing, image.id), data: { confirm: 'Are you sure?' }, :method => :delete, :class => 'delete' %></span>
        </li>
    <% end %>
</ul>

我相信你的问题是这个和你的图像控制器索引动作的组合。

点击索引操作后,您可以创建新记录@image = @listing.images.new

现在您的@listing.images.each调用注册了尚未保存的对象。