Требуется ли для получения current_user соответствующее представление?

В моем контроллере у меня есть действие, у которого нет соответствующего представления. Точно: действие загрузки для загрузки изображений. Однако мне требуется текущий идентификатор пользователя для хранения URL-адреса изображения. Но метод current_user всегда возвращает nil, так как действие само по себе не имеет представления. Как в таких случаях получить current_user? Я использую аутлогик. Мой application_controller.rb содержит следующее:

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

РЕДАКТИРОВАТЬ: все остальные действия в контроллере могут получить доступ к вспомогательному методу current_user. Только действие upload не умеет. Код:

Контроллер:

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

Модель:

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

person Shripad Krishna    schedule 02.08.2010    source источник


Ответы (1)


Метод контроллера на самом деле просто метод класса. Это не требует представления. Я делаю это закрытым методом, метод недоступен вне класса или других классов, наследуемых от него, и поэтому он правильно недоступен для представления. Ваша проблема предполагает, что ваш пользователь не вошел в систему или что-то еще не так. У вас есть метод require_user?

#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)

Редактировать:

Ваш метод current_user является методом ApplicationController, который уже унаследован:

ImageStacksController < ApplicationController

Этот:

helper_method :current_user_session, :current_user

предоставляет методы для представления.

Разница между действием загрузки и всеми остальными заключается в том, что обновление вызывается javascript. Я помню, как делал аналогичный загрузчик и должен был передать токен подлинности. Сообщается ли что-нибудь еще в журнале?

Это может быть вам полезно: http://github.com/JimNeath/swfupload---paperclip-example-app

Сделать токен подлинности доступным для js можно примерно так:

- content_for :head do
  = javascript_tag "var AUTH_TOKEN = #{form_authenticity_token.inspect};" if protect_against_forgery?

Теперь вы добавляете поле в swflupload так же, как вы добавляли current_user.

person mark    schedule 02.08.2010
comment
Я делаю его доступным для других классов, наследующих его, с помощью вспомогательного метода :current_user. Действие upload — это единственное действие, которое не может получить доступ к методу current_user. Однако другие действия в том же контроллере могут получить к нему доступ! Действительно, очень странно!! Я обновлю свой вопрос с кодом действия upload. - person Shripad Krishna; 02.08.2010
comment
В журнале больше ничего не сообщается, кроме того факта, что current_user равен нулю! Итак, если вспомогательные методы предназначены для представлений, все, что мне нужно сделать, это передать current_user в качестве параметра с помощью swfupload!! Да, я получил это сейчас. Спасибо :) - person Shripad Krishna; 02.08.2010
comment
Хотя это может сработать, это небезопасно — пользователь может создать изображение, маскирующееся под другого пользователя. Я действительно думаю, что вам нужно изучить возможность передачи токена подлинности с помощью swfupload и require_user в вашем контроллере изображения. Добавил небольшую правку выше. - person mark; 02.08.2010
comment
Самое смешное, что это не очень хорошо работает с аутентификацией. Я использую authlogic для аутентификации пользователей. Информация о сеансе просто недоступна для действия upload!! Я пробовал много учебников, но безрезультатно. Любые данные по этому поводу? - person Shripad Krishna; 10.08.2010