Does fetching current_user require a corresponding view?
In my controller i have an action which does not have a corresponding view. Precisely: the upload action for uploading images. However, i require the current users id to store the image url. But the current_user method always returns nil, as the action by itself does not have a view. In such scenarios how do i fetch the current_user? I am using authlogic. My application_controller.rb contains the following:
class ApplicationController < ActionController::Base
helper :all
helper_method :current_user_session, :current_user
filter_parameter_logging :password, :password_confirmation
protect_from_forgery
def correct_safari_and_ie_accept_headers
ajax_request_types = [ 'application/json', 'text/javascript', 'text/xml']
request.accepts.sort!{ |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr?
end
private
def set_cache_buster
response.headers["Cache-Control"] = "no-cache, no-store, max-age=0, must-revalidate"
response.headers["Pragma"] = "no-cache"
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
end
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session && current_user_session.record
end
end
EDIT: All other actions in the controller are able to access the current_user
helper method. Only the upload
action is not able to. Code:
Controller:
class ImageStacksController < ApplicationController
def upload
# Using swfupload.
image_stack_params = {
:caption => params[:caption],
:swf_uploaded_data => params[:link]
}
# current_user returns nil, even with user logged in!!
# Occurs only in the upload action and no other action in this controller.
logger.info("Current User: #{current_user}") #Returns nil
@image_stack = current_user.image_stacks.create! image_stack_params
respond_to do |format|
format.js { render :json => @image_stack }
end
end
def edit
logger.info("Current User: #{current_user}") #Returns current user
end
def new
logger.info("Current User: #{current_user}") #Returns current user
end
def update
logger.info("Current User: #{current_user}") #Returns current user
end
def destroy
logger.info("Current User: #{current_user}") #开发者_高级运维Returns current user
end
end
Model:
class ImageStack < ActiveRecord::Base
belongs_to :user, :class_name => "User", :foreign_key => "user_id"
upload_image_to_s3 :link
def swf_uploaded_data=(data)
data.content_type = MIME::Types.type_for(data.original_filename)
self.link = data
end
end
The controller method is really just that, a class method. It does not require a view. My making it a private method the method is not available outside the class or other classes inheriting from it and as such it is correctly not available to the view. Your problem suggests that your user is not logged in or something else is wrong. Do you have a require_user method?
#application_controller
private
def require_user
unless current_user
store_location
flash[:notice] = t(:must_be_logged_in)
redirect_to user_login_path
return false
end
end
def store_location
session[:return_to] = request.request_uri
end
#user.rb
has_many :images
#image.rb
belongs_to :user
# image_controller.rb
before_filter :require_user
def create
@photo = @item.images.new(:photo => params[:photo], :user => current_user)
Edit:
Your current_user method is a ApplicationController method which is already inherited:
ImageStacksController < ApplicationController
This:
helper_method :current_user_session, :current_user
is providing the methods to the view.
The difference between the upload action and all the others is update is being called by javascript. I remember doing a similar uploader and having to pass the authenticity token. Is anything else being reported in the log?
This might be of use to you: http://github.com/JimNeath/swfupload---paperclip-example-app
Making the authenticity token available to js goes something like this:
- content_for :head do
= javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery?
Now you add the field to swflupload the same way you added current_user.
精彩评论