Rails: дублирование функциональности на контроллерах? Скромная просьба - PullRequest
1 голос
/ 19 мая 2010

Итак, я работаю с authlogic и пытаюсь продублировать функцию входа в систему на странице приветствия, чтобы вы могли войти в систему с помощью URL-адреса restful или просто перейдя на главную страницу. Нет, я не знаю, сохраним ли мы эту функцию, но я все равно хочу ее проверить. Вот сообщение об ошибке:

RuntimeError in Welcome#index Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id

Код ниже. По сути, происходит то, что представление индекса (первый фрагмент кода) отправляет информацию из формы в метод create контроллера user_sessions. На данный момент, теоретически, его создание должно просто забрать, но это не так.

ПОЖАЛУЙСТА, помогите. Пожалуйста. Я занимаюсь этим около 8 часов. Я проверил Google. Я проверил IRC. Я проверил каждую книгу, которую смог найти. Тебе даже не нужно отвечать, я могу выполнить грубую работу, если ты просто укажешь мне правильное направление.

=== РЕДАКТИРОВАНИЕ РЕДАКТИРОВАНИЕ РЕДАКТИРОВАНИЕ ===

Самера была достаточно хороша, чтобы дать ответ на проблему. Открытый вопрос, однако, каков наилучший способ организовать приложение? Является ли применение объекта @user_sessions в before_filter приемлемым или есть более удобный способ сделать это?

WELCOME # INDEX

<% form_for @user_session, :url => user_sessions_path do |f| %>
    <%= f.text_field :email %><br />
<%= f.password_field :password %>
<%= submit_tag 'Login' %>
<% end %>

КОНТРОЛЛЕР ПРИМЕНЕНИЯ

class ApplicationController < ActionController::Base
  helper :all # include all helpers, all the time
  protect_from_forgery # See ActionController::RequestForgeryProtection for details
  # Scrub sensitive parameters from your log
  # filter_parameter_logging :password
    helper_method :current_user_session, :current_user
    before_filter :new_session_object
protected
    def new_session_object
        unless current_user
        @user_session = UserSession.new(params[:user_session])
    end
end
private
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<pre></code>

КОНТРОЛЛЕР СЕССИЙ ПОЛЬЗОВАТЕЛЯ

class UserSessionsController < ApplicationController
  def new
    @user_session = UserSession.new
  end

  def create
    @user_session = UserSession.new(params[:user_session])
    if @user_session.save
      flash[:notice] = "Logged in"
      redirect_to root_url
    else
      render :controller => 'user_sessions', :action => 'new'
    end
  end

  def destroy
    @user_session = UserSession.find
    @user_session.destroy
    flash[:notice] = "Logged out"
    redirect_to root_url
  end
end

Более подробный STACK TRACE

1: <h1>Welcome#index</h1>
2: <p>Find me in app/views/welcome/index.html.erb</p>
3: 
4: <% form_for @user_session, :url => user_sessions_path do |f| %>
5:  <%= f.text_field :email %><br />
6:      <%= f.password_field :password %>
7:  <%= submit_tag 'Login' %>

Application Trace | Framework Trace | Full Trace
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpac -2.3.5/lib/action_controller/record_identifier.rb:76:in `dom_id'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/record_identification_helper.rb:16:in `dom_id'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:293:in `apply_form_for_options!'
/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/lib/ruby/gems/1.8/gems/actionpack-2.3.5/lib/action_view/helpers/form_helper.rb:277:in `form_for'
/Users/alex/Desktop/anglic/app/views/welcome/index.html.erb:4:in `_run_erb_app47views47welcome47index46html46erb'

Ответы [ 3 ]

1 голос
/ 19 мая 2010

Вы должны добавить следующий метод в ApplicationController:

def require_user
    unless current_user
        flash[:notice] = "You must be logged in to access this page!"
        redirect_to :controller => "user_sessions", :action => "new"            
        return false
    end
end

Затем в WelcomeController добавьте фильтр перед следующим образом:

before_filter :require_user 

Теперь любой, кто получает доступ к WelcomeController, будет перенаправлен на страницу входа. Вам не нужно дублировать функциональность между контроллерами.

Для получения подробной информации пройдите учебник по настройке Authlogic: http://rdoc.info/projects/binarylogic/authlogic

0 голосов
/ 19 мая 2010

Попробуйте это:

form_for :user_session, @user_session, :url => user_session_path(@user_session)} do |f| 

end
0 голосов
/ 19 мая 2010

Я думаю, вы можете попробовать это в вашем WelcomeController

class WelcomeController < ActionController::Base

  def index
    @user_session = UserSession.new
    .....
  end

  ..... 

end

Мне кажется, что вы пытаетесь использовать @user_session, который не определен в представлении действия индекса WelcomeController.

Надеюсь, это поможет.

РЕДАКТИРОВАТЬ # 1

Мне кажется, что проблема возникает при вызове before_filter после отправки формы в действии WelcomeController # index.

Этот конкретный фрагмент кода для меня странен

class ApplicationController < ActionController::Base

  .....
  private
  def current_user_session
    return @current_user_session if defined?(@current_user_session)
    @current_user_session = UserSession.find
  end
  .....

end

Я совершенно уверен, UserSession.find сломается.

Надеюсь, это редактирование поможет.

РЕДАКТИРОВАТЬ # 2

Еще одна вещь, которая показалась мне странной, находится внутри защищенного метода new_session_object:

protected
    def new_session_object
        unless current_user
        @user_session = UserSession.new(params[:user_session])
    end
end

Любая причина, по которой UserSession.new был создан с params[:user_session]?

Поток для вашего UserSessionController логина, насколько я понимаю:

  1. before_filter :new_session_object называется

  2. вернется false для current_user так как это новый сеанс пользователя

  3. будет установлена ​​@user_session переменная в UserSession.new(params[:user_session]) значение

  4. UserSessionController#new действие называется который переопределить @user_session переменная до UserSession.new

  5. new.html.erb отображается содержащий форму для входа в систему

  6. before_filter :new_session_object is снова позвонил

  7. вернется false за current_user так как это все еще новый пользовательский сеанс

  8. будет установлено @user_session переменная в UserSession.new(params[:user_session]) значение

  9. UserSessionController#create называется действие, которое снова установите переменную @user_session в UserSession.new(params[:user_session]) значение.

  10. @user_session сохраняется и пользовательский сеанс успешно создано

НО для WelcomeController слегка отличается на шаге 4

Значение переменной @user_session, которое используется в WelcomeController#index, получено из before_filter назначения переменной вызова UserSession.new(params[:user_session]), в этот момент значение params[:user_session] равно nil, поэтому @user_session = UserSession.new(nil) Я ndex.html.erb был предоставлен.

Я не совсем уверен, является ли это причиной вашей проблемы, но это может помочь вам решить эту проблему, если вы запустите script/server --debugger и выполните создание @user_session при использовании WelcomeController, особенно когда форма размещена на UserSessionController#create.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...