Ruby on rails - 嵌套表单,未保存的属性(使用回形针上传图像)

时间:2013-11-28 19:16:56

标签: ruby-on-rails ruby paperclip nested-forms image-uploading

我已经按照harlt的教程开始使用ruby。现在我想在我的微博中添加图片。当我使用简单的表格上传图片时,它的工作原理。当我想以微博的形式上传图片时,会创建图片,但所有属性都是空的。

简单上传图片的服务器日志

Started POST "/photos" for 127.0.0.1 at 2013-11-28 17:50:33 +0100
Processing by PhotosController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"u7MWO+E9jM8/g+6RwquQ7XLA3PR+ohQFAx0tmwNOfuY=", "photo"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007f77b93b2710 @tempfile=#<Tempfile:/tmp/RackMultipart20131128-19203-ypziwp>, @original_filename="photoiphone.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"photo[image]\"; filename=\"photoiphone.jpg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Create Photo"}
  #[1m#[36mUser Load (0.3ms)#[0m  #[1mSELECT "users".* FROM "users" WHERE "users"."remember_token" = '4c0f0085d819eec94a9d0eba0175fb7642fe4976' LIMIT 1#[0m
  #[1m#[35m (0.1ms)#[0m  begin transaction
Binary data inserted for `string` type on column `image_content_type`
  #[1m#[36mSQL (0.6ms)#[0m  #[1mINSERT INTO "photos" ("created_at", "image_content_type", "image_file_name", "image_file_size", "updated_at") VALUES (?, ?, ?, ?, ?)#[0m  [["created_at", Thu, 28 Nov 2013 16:50:33 UTC +00:00], ["image_content_type", "image/jpeg"], ["image_file_name", "photoiphone.jpg"], ["image_file_size", 51874], ["updated_at", Thu, 28 Nov 2013 16:50:33 UTC +00:00]]
  #[1m#[35m (180.2ms)#[0m  commit transaction
Redirected to http://localhost:3000/photos/15
Completed 302 Found in 191ms (ActiveRecord: 181.2ms)

以微博形式上传图片的服务器日志

Started POST "/microposts" for 127.0.0.1 at 2013-11-28 17:49:02 +0100
Processing by MicropostsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"u7MWO+E9jM8/g+6RwquQ7XLA3PR+ohQFAx0tmwNOfuY=", "micropost"=>{"content"=>"test pour log", "photo_attributes"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007f77b8871248 @tempfile=#<Tempfile:/tmp/RackMultipart20131128-19203-199w522>, @original_filename="paint.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"micropost[photo_attributes][image]\"; filename=\"paint.jpg\"\r\nContent-Type: image/jpeg\r\n">}}, "commit"=>"Post"}
  #[1m#[36mUser Load (0.2ms)#[0m  #[1mSELECT "users".* FROM "users" WHERE "users"."remember_token" = '4c0f0085d819eec94a9d0eba0175fb7642fe4976' LIMIT 1#[0m
  #[1m#[35m (0.1ms)#[0m  begin transaction
  #[1m#[36mSQL (0.9ms)#[0m  #[1mINSERT INTO "microposts" ("content", "created_at", "updated_at", "user_id") VALUES (?, ?, ?, ?)#[0m  [["content", "test pour log"], ["created_at", Thu, 28 Nov 2013 16:49:02 UTC +00:00], ["updated_at", Thu, 28 Nov 2013 16:49:02 UTC +00:00], ["user_id", 101]]
  #[1m#[35mSQL (0.3ms)#[0m  INSERT INTO "photos" ("created_at", "micropost_id", "updated_at") VALUES (?, ?, ?)  [["created_at", Thu, 28 Nov 2013 16:49:02 UTC +00:00], ["micropost_id", 21], ["updated_at", Thu, 28 Nov 2013 16:49:02 UTC +00:00]]
  #[1m#[36m (147.9ms)#[0m  #[1mcommit transaction#[0m
Redirected to http://localhost:3000/
Completed 302 Found in 161ms (ActiveRecord: 149.3ms)

我们可以看到第Binary data inserted for string type on column image_content_type行只出现在第一个日志中。

用户控制器

class UsersController < ApplicationController
  before_action :signed_in_user, only: [:index, :edit, :update]
  before_action :correct_user,   only: [:edit, :update]

  def new
    @user = User.new
  end

  def index
    #@users = User.all
    @users = User.paginate(page: params[:page])
  end

  def show
    @user = User.find(params[:id])
    @micropost = current_user.microposts.build
    @photo = @micropost.build_photo
    @microposts = @user.microposts.paginate(page: params[:page])
    @feed_items = current_user.feed.paginate(page: params[:page])
  end

  def create
    @user = User.new(user_params)
    if @user.save
      sign_in @user
      flash[:success] = "Welcome to the PYL!"
      redirect_to @user
    else
      render 'new'
    end
  end

  def edit
    @user = User.find(params[:id])
  end

  def update
    if @user.update_attributes(user_params)
      flash[:success] = "Profile updated"
      redirect_to @user
    else
      render 'edit'
    end
  end


  private

    def user_params
      params.require(:user).permit(:name, :email, :password, :password_confirmation)
    end

    def signed_in_user
      store_location
      redirect_to signin_url, notice: "Please sign in." unless signed_in?
    end

    def correct_user
      @user = User.find(params[:id])
      redirect_to(root_url) unless current_user?(@user)
    end

end

查看show for user呈现此表单

<%= form_for @micropost, :html => { :multipart => true }  do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="field">
    <%= f.text_area :content, placeholder: "Compose new micropost..." %>

</div>
<%= f.fields_for :photo do |builder| %>
<%= file_field :image, :f=>builder %>
<% end %>
<%= f.submit "Post", class: "btn btn-large btn-primary" %>
<% end %>

数据库

  create_table "microposts", force: true do |t|
    t.string   "content"
    t.integer  "user_id"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.integer  "photo_id"
  end

  add_index "microposts", ["user_id", "created_at"], name: "index_microposts_on_user_id_and_created_at"

  create_table "photos", force: true do |t|
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "image_file_name"
    t.string   "image_content_type"
    t.string   "image_file_size"
    t.string   "image_update_at"
    t.integer  "micropost_id"
  end

对于简单的图片上传,我使用以下代码:

照片控制器

class PhotosController < ApplicationController
  before_action :signed_in_user, only: [:create, :index]
  before_action :set_photo, only: [:show, :edit]

  def index
    @photos = Photo.all
  end

  def show
  end

  def new
    @photo = Photo.new
  end

  def edit
  end

  def create
    @photo = Photo.new(photo_params)

    respond_to do |format|
      if @photo.save
        format.html { redirect_to @photo, notice: 'Photo was successfully created.' }
        format.json { render action: 'static_pages/home', status: :created, location: @photo }
      else
        format.html { render action: 'static_pages/home' }
        format.json { render json: @photo.errors, status: :unprocessable_entity }
      end
    end
  end

  private
    def set_photo
      @photo = Photo.find(params[:id])
    end

    def photo_params
      params.require(:photo).permit(:image)
    end
end

并在视图中新建

<%= form_for @photo, :html => { :multipart => true } do |f| %>
<%= f.file_field :image %>
<%= f.submit %>
<% end %>

我使用SQLite Manager查看我的数据库。 我还有一个微博控制器并且不知道它是如何工作的,因为它适用于没有图片的微博,但我想我需要在我的用户控制器中使用micropost_params,但我不能访问它。

class MicropostsController < ApplicationController
  before_action :signed_in_user, only: [:create, :destroy]
  before_action :correct_user,   only: :destroy



  def create
    @micropost = current_user.microposts.build(micropost_params)
    @photo = @micropost.build_photo
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to root_url
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end

  def destroy
    @micropost.destroy
    redirect_to root_url
  end

  private

  def micropost_params
    params.require(:micropost).permit(:content, photo_attributes: [image:  
                [:image_file_name, :image_content_type, :image_file_size, :image_update_at]])
  end

  def correct_user
    @micropost = current_user.microposts.find_by(id: params[:id])
    redirect_to root_url if @micropost.nil?
  end

感谢您的帮助:) !!

1 个答案:

答案 0 :(得分:0)

如果您调用builder.file_field:image而不是file_field:image,:f =&gt; :建造者?