Ruby on Rails — макет рендеринга

Я пытаюсь разделить веб-сайт на две части. Тот, который должен использовать макет приложения, и тот, который должен использовать макет администратора. В моем application.rb я создал следующую функцию:

def admin_layout
  if current_user.is_able_to('siteadmin')
    render :layout => 'admin'
  else
    render :layout => 'application'
  end
end

А в контролерах где может быть и то и другое ставлю

before_filter :admin_layout

Это отлично работает для некоторых страниц (где это просто текст), но для других я получаю классическую ошибку:

You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each

Кто-нибудь знает, что мне не хватает? Как мне правильно использовать рендеринг и макет?


person RyanJM    schedule 14.07.2009    source источник


Ответы (5)


Метод render на самом деле попытается отобразить содержимое; вы не должны вызывать его, когда все, что вы хотите сделать, это установить макет.

В Rails заложен шаблон для всего этого. Просто передайте символ layout, и будет вызван метод с таким именем, чтобы определить текущий макет:

class MyController < ApplicationController
  layout :admin_layout

  private

  def admin_layout
    # Check if logged in, because current_user could be nil.
    if logged_in? and current_user.is_able_to('siteadmin')
      "admin"
    else
      "application"
    end
  end
end

Подробности см. здесь.

person molf    schedule 14.07.2009
comment
если залогинился? и current_user.is_able_to('siteadmin') поскольку current_user может быть нулевым, если он не вошел в систему! - person Reuben Mallaby; 15.07.2009
comment
У меня есть другие проверки перед этой строкой, чтобы проверить, вошел ли пользователь в систему. Это удивительно, хотя я никогда даже не думал о вызове функции после макета. Так просто и очень полезно. Спасибо. - person RyanJM; 15.07.2009
comment
Для тех, кто проверяет это. Я должен был провести немного больше исследований: apidock.com/rails/ActionController/Layout/ClassMethods /layout первый комментарий ответил бы на мой вопрос. - person RyanJM; 16.07.2009
comment
@molf ссылка в вашем ответе не работает - person Kick Buttowski; 10.03.2017

возможно, вам нужно сначала проверить, что пользователь вошел в систему?

def admin_layout
  if current_user and current_user.is_able_to 'siteadmin'
    render :layout => 'admin'
  else
    render :layout => 'application'
  end
end
person Community    schedule 14.07.2009
comment
.ноль? на операторе, если это избыточно, хотя - person Gav; 15.07.2009

Это может быть связано с тем, что current_user является nil, когда пользователь не вошел в систему. Либо проверьте .nil?, либо инициализируйте объект.

person marcgg    schedule 14.07.2009

Попробуйте ответить на молф:

если залогинился? и current_user.is_able_to('администратор сайта')

person Reuben Mallaby    schedule 15.07.2009

Ваш текущий пользователь правильно настроен после того, как пользователь вошел в систему. В этом случае у вас должна быть возможность определить, вошли ли вы в систему.

как

 if !@current_user.nil?
   if @current_user.is_able_to("###")
     render :layout => "admin"
   else
    render :layout => "application"
   end
 end

Затем он будет вводить оператор if только в том случае, если ваш @current_user не равен нулю.

person Dee-M    schedule 15.07.2009