在 2 布局中使用 1 个控制器

Using 1 Controller in 2 layout

我有一道逻辑题,我不知道该怎么做。首先,我在一个社交网站上工作,我在纯 PHP 完成了这个网站,但现在我 re-writing rails 中的后端。

我的问题是,我生成了 UsersController,它有新建、创建、显示、编辑、更新、删除和销毁。

我想我可以使用 "new" 显示注册页面,"create" 处理注册,"show" 显示个人资料页面,"edit" 显示帐户设置"update" 处理编辑。

我这里可能有逻辑问题,也许我应该将 "new" 和 "create" 放在注册控制器中。这是我感到困惑的地方。我说的第一个逻辑的问题,我有2个布局,一个是登录前的,另一个是登录后的。 (你可以想象Facebook在登录前和登录后的header)。

因此,当我有 2 个不同的布局时,我不能在 2 个布局中使用 1 个控制器。因为注册页面有 "before login header design",帐户设置和个人资料有 "after login header design"。你可以猜到我在控制器中定义了布局。

不知道我解释的好不好。谢谢。

Rails 具有基本的 CRUD 默认操作。此外,每个操作都可以根据 HTTP 谓词进行不同的处理。您还可以添加自定义操作和路由。

每个默认操作最好遵循标准 Rails 做法。例如,"new" 操作应该路由到表单以在通过 GET 访问时创建新用户。表单的 HTTP POST 应该路由到 "create" 操作。

如果您需要添加额外的控制器操作,请使用自定义方法。我再次强调,简单的 CRUD 操作应该遵循正常的 Rails 约定。

详细了解 routing
多次阅读本指南以了解 simple CRUD actions in Rails

默认情况下,Rails 将查找与控制器同名的布局,否则 application.html.erb。但是你也可以在整个控制器范围内指定一个(这对你没有帮助,但请耐心等待)

class SomethingController
  layout "some_name"
  ...

这仍然是布局范围内的,所以不是您所需要的。

但您也可以在操作中每次调用 render 时指定特定布局:

def edit
   #some logic
   render "some_template", :layout => "some_layout"
end

或者,采用默认模板查找,但仍指定布局:

def edit
   # some logic
   render :layout => "some_layout"
end

还有另一种方法可以指定布局,这可能特别适合 "one layout if not logged in, another if logged in":

的用例
class SomeController
   layout :method_name_to_determine_layout

   # ... actions ...

   protected
   def method_name_to_determine_layout
     if current_user
        "logged_in_layout_name"
     else
        "not_logged_in_layout_name"
     end
   end

您可以在 Layouts and Rendering Rails Guide

中详细了解指定布局的不同方法

希望这对您有所帮助。

我决定使用单独的控制器,而不是在 2 个布局中使用 1 个控制器。因此,我有 profile_controller,其中 "edit" 和 "update" 用于帐户设置,"show" 用于显示个人资料。我还 users_controller,其中包含以下内容:登录、login_attempt、注册、signup_attempt 等。

所以,我没有将注册和编辑放在 1 个控制器中,而是使用 2 个不同的控制器更好更干净,我想。

听起来您正在尝试推出自己的身份验证。

我建议使用 Devise... great tutorial here:

这有两个原因。

首先,Devise 使您能够在经过身份验证的用户和未经过身份验证的用户之间划分您的应用程序。也就是说,它提供了 user_signed_in?, devise_controller? and current_user 助手来帮助解决这个问题。

这可能看起来没什么大不了的,但它实际上可以帮助您进行布局(稍后我会详细介绍)。

其次,设计是预卷的。您关于如何处理 signupsregistrations 的问题已经解决。当然,没有什么可以阻止您进行自己的身份验证(毕竟 Devise 只是基于 Warden 构建的),但它应该让您了解如何完成此操作。


关于你原来的问题(关于布局),另一个答案非常好(在每个方法的设置 layouts 等方面)。

补充一点,我要说的是你必须记住 Rails 是一系列 类。因此,在 controller 中设置 layout 选项是确保您获得正确选项的最佳方式。

这里是Rails explanation on it

#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
   layout :your_layout

   private

   def your_layout
      devise_controller? || !user_signed_in? ? "new_user" : "application"
   end
end

我发现最好让您的逻辑尽可能简洁。 IE 只有一套布局逻辑。我们倾向于将其保留在 ApplicationController 中,必要时覆盖。

--

最后,您的问题还强调了对 Rails 的基本误解。我不是不尊重;我发现您对框架的认识越清楚,您就越能使用它:

用Rails要记住几个要点:

  1. 它是一个 MVC (M模型 View Controller) 框架
  2. 它建立在 Ruby 之上;因此面向对象

maybe I should put "new" and "create" in a signup controller. This where I get confused.

如果您将 Devise 作为模型,您会发现您可以将控制器视为 对象 的抽象层。也就是说,正如 Devise 向我们展示的那样,您可以拥有 sessionsregistrations 控制器。

我不是提倡你完全这样做,我 试图表明如果你把焦点放在 对象上 你正在处理,您的控制器操作应该放在哪里变得更加清晰。

你也会最好地理解 CRUD (Create Read U pdate Destroy) Rails 控制器和对象的性质。标准 Rails 控制器设置如下:

虽然这并不严格,但确实 为您提供了有关控制器应遵循的结构的另一个指示。

你可能已经知道这些东西了!