Rails file_field标记仅将String文件名传递给控制器

时间:2017-10-02 17:29:42

标签: ruby-on-rails string filefield

我的file_field标记只传递文件名,而不是文件本身传递给控制器​​。

在我的用户模型中:

mount_uploader :avatar, AvatarUploader
validate :avatar_size
...
def avatar_size
  errors.add :avatar, "should be less than 5MB" if avatar.size > 5.megabytes
end

AvatarUploader:

class AvatarUploader < CarrierWave::Uploader::Base

  include CarrierWave::MiniMagick
  process resize_to_limit: [50, 50]

  if Rails.env.production?
    storage :fog
  else
    storage :file
  end

  def store_dir
    "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
  end

  def extension_white_list
    %w(jpg, jpeg, gif, png)
  end

end

用户控制器:

before_action :logged_in_user, only: [:index, :edit, :update, :destroy, :following, :followers]
before_action :correct_user, only: [:edit, :update]
before_action :admin_user, only: [:destroy]
skip_before_action :verify_authenticity_token, only: [:create]
...
def update
  @user = User.find(params[:id])
  if @user.update_attributes user_params
    flash[:success] = "Profile updated"
    redirect_to user_path @user
  else
    render 'edit'
  end
end
...
def user_params
  params.require(:user).permit :name, :email, :password, :password_confirmation, :avatar
end

def correct_user
  @user = User.find params[:id]
  redirect_to root_path unless @user == current_user
end

def admin_user
  redirect_to root_path unless current_user.admin?
end

视图中的表单:

<%= form_for(@user) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>

  <%= f.label :name %>
  <%= f.text_field :name, class: 'form-control' %>

  <%= f.label :email %>
  <%= f.email_field :email, class: 'form-control' %>

  <%= f.label :password %>
  <%= f.password_field :password, class: 'form-control' %>

  <%= f.label :password_confirmation %>
  <%= f.password_field :password_confirmation, class: 'form-control' %>

  <% if @user.avatar? %>
    <%= image_tag @user.avatar.url, size: "50x50" %>
  <% else %>
    <%= image_tag "stock_ava.png", size: "50x50" %>
  <% end %>

  <%= f.file_field :avatar, accept: 'image/jpeg,image/gif,image/png' %>

  <%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>

在控制台中,我可以看到属性来自&#34; FinnJake.png&#34;,而不是相应的ActionDispatch。

Processing by UsersController#update as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"h9tD/g2M1zJ5L4cnysIQwHCWxDdhhhJR1I9a9+FAWeT9aTXPte16Uyn8GvI4w23klfvYtTaLCDrGVonHfmFUag==", "user"=>{"name"=>"Example User", "email"=>"example@user.com", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]", "avatar"=>"FinnJake.png"}, "commit"=>"Save Changes", "id"=>"1"}
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
  CACHE User Load (0.0ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = ? LIMIT ?  [["id", 1], ["LIMIT", 1]]
   (0.1ms)  begin transaction
  User Exists (0.3ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND ("users"."id" != ?) LIMIT ?  [["email", "bexample@user.com"], ["id", 1], ["LIMIT", 1]]
  SQL (1.1ms)  UPDATE "users" SET "avatar" = ?, "updated_at" = ? WHERE "users"."id" = ?  [["avatar", nil], ["updated_at", "2017-10-02 14:50:41.226691"], ["id", 1]]
   (142.3ms)  commit transaction
Redirected to https://rubyonrails-xxx.c9users.io/users/1
Completed 302 Found in 155ms (ActiveRecord: 144.1ms)

我对rails非常陌生,但我无法弄清楚为什么file_field没有上传文件。我可以在浏览器中看到我最终得到这个标签:

<input accept="image/jpeg,image/gif,image/png" type="file" name="user[avatar]" id="user_avatar">

哪个看起来对我好。我似乎也无法通过rails控制台手动更新该列,但我没有收到任何错误:

2.4.0 :002 > user = User.first
  User Load (0.5ms)  SELECT  "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ?  [["LIMIT", 1]]
 => #<User id: 1, name: "Example User", email: "example@user.com", created_at: "2017-10-02 14:32:22", updated_at: "2017-10-02 16:35:55", password_digest: "$2a$10$sww7gItks0mYz6xz8zV.QOIjr6to/o5Jytjmuo0wxny...", remember_digest: nil, admin: true, activation_digest: "$2a$10$W396r7A8aZaii3DC7b3W7u70etSmXh3MORMIoWtcSHo...", activated_at: "2017-10-02 14:32:22", reset_digest: nil, reset_sent_at: nil, avatar: nil> 
2.4.0 :003 > user.update avatar: "String"
   (0.2ms)  begin transaction
  User Exists (0.4ms)  SELECT  1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER(?) AND ("users"."id" != ?) LIMIT ?  [["email", "example@user.com"], ["id", 1], ["LIMIT", 1]]
  SQL (2.4ms)  UPDATE "users" SET "updated_at" = ?, "avatar" = ? WHERE "users"."id" = ?  [["updated_at", "2017-10-02 17:27:06.097363"], ["avatar", nil], ["id", 1]]
   (11.4ms)  commit transaction
 => true 

提前感谢您提供的任何建议。

2 个答案:

答案 0 :(得分:1)

您应该使用多部分表单,如:

SELECT Book.title, lastname, firstname
FROM Book, Member
WHERE Book.title like '%XML%XQuery%' or title like '%XQuery%XML%'
AND EXISTS (SELECT Book.bookID, Member.memberID
    FROM Member, Book, CurrentLoan
    WHERE Book.bookID = CurrentLoan.bookID
    AND Member.memberID = CurrentLoan.memberID);

请参阅http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-file_field

答案 1 :(得分:0)

发现问题。见this comment

基本上,partial中的表单被另一个具有不同编码类型的表单包装。