使用carrierwave我的用户现在可以上传自己的头像了!好极了!这是我的更新操作:
def update
@image = @user.create_avatar(file_name: user_params[:avatar][:file_name])
respond_to do |format|
if @user.update_attributes(user_params.delete avatar: [:file_name]) # this automatically deletes any avatar instances, as uploaded files are saved in a seperate model
format.html { redirect_to @user, notice: 'User was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: 'edit' }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
这是我的表格:
<%= form_for(@user, :html => { :multipart => true }) do |f| %>
<%= f.fields_for :avatar do |f| %>
<%= f.file_field :file_name %>
<%= f.submit %>
<% end %>
<% end %>
但是,当有人没有上传头像时,上述操作会爆发,因为首先user_params
没有:avatar
键,因此调用[:file_name]
会导致未定义的方法没有错误。
我可以通过条件轻松解决这个问题,但是我应该创建一个单独的动作来更新我的头像吗?可能def avatar_update
?我只是不确定最好的rails方式,因为我有一个单独的Image模型,但我不觉得这样的动作应该进入图像控制器,因为用户模型有这样的关系:
has_one :avatar, class_name: 'Image', foreign_key: :user_id
对我来说,它确实感觉就像avatar_update
动作“属于”用户控制器和图像控制器之间的某处,所以我真的不知道放在哪里。将它放在图像控制器中会是RESTful,但是在未来的某个时刻,图像模型将属于许多不同的模型。这一思路会导致图像控制器中的几个动作沿着avatar_update
和photo_update
以及panorama_update
,post_image_update
以及我的应用程序的不同类型的各种事物图像。
那么我应该在哪里进行update_avatar
动作?
答案 0 :(得分:1)
尽管图像与多个模型相关联,但您的所有图片上传都足够相似,您可以在图像控制器中保留一个update
操作。此操作将更新图像,然后重定向到相关记录所在的#show
页面。想象一下,图像可以属于用户,文章或专辑:
class ImagesController < ApplicationController
...
def update
if @image.update_attributes(image_params)
redirect_to @image.associated_record, notice: 'Image was successfully updated.'
else
render action: 'edit'
end
end
end
class Image < ActiveRecord::Base
...
def associated_record
user || article || album
end
end
另一种可能性是,根据与之关联的模型,每个图像#update
动作将会非常不同。在这种情况下,在其关联模型下创建多个ImageController
个命名空间,每个模型都有自己的#update
操作。例如:
# in app/controllers/users/images_controller.rb
class Users::ImagesController < ApplicationController
end
# in config/routes.rb
resources :users do
resources :images, controller: 'users/images'
end
资料来源:Rails AntiPatterns:最佳实践Ruby on Rails Refactoring,“Rat's nest resources”一章