【问题标题】:Using 1 Controller in 2 layout在 2 布局中使用 1 个控制器
【发布时间】:2015-09-22 00:19:43
【问题描述】:

我有一个逻辑问题,我不知道该怎么做。首先,我在做一个社交网站,我用纯PHP完成了这个网站,但现在我正在用rails重写后端。

我的问题是,我生成了 UsersController,它有 new、create、show、edit、update、delete 和 destroy。

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

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

所以,当我有 2 个不同的布局时,我不能在 2 个布局中使用 1 个控制器。因为注册页面有“登录前标头设计”,而账户设置和个人资料有“登录后标头设计”。你可以猜到我在控制器中定义了布局。

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

【问题讨论】:

    标签: ruby-on-rails logic social-networking


    【解决方案1】:

    默认情况下,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
    

    还有另一种方式可以指定布局,这可能特别适合“一个布局如果未登录,另一个布局如果登录”的用例:

    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】:

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

    对于每个默认操作,最好遵循标准 Rails 实践。例如,当通过 GET 访问时,“新”操作应路由到表单以创建新用户。表单的 HTTP POST 应该路由到“创建”操作。

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

    阅读更多关于routing
    多次阅读本指南了解simple CRUD actions in Rails

    【讨论】:

      【解决方案3】:

      我决定使用单独的控制器,而不是在 2 个布局中使用 1 个控制器。所以,我有 profile_controller,它具有用于帐户设置的“编辑”和“更新”以及用于显示配置文件的“显示”。而且我还有users_controller,里面有login、login_attempt、signup、signup_attempt等。

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

      【讨论】:

        【解决方案4】:

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

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

        原因有两个。

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

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

        其次,Devise 是预滚动的。您关于如何处理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(Model View Controller)框架
        2. 它基于 Ruby 构建;因此是面向对象的

        也许我应该将“new”和“create”放在注册控制器中。这让我感到困惑。

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

        我并不是在提倡你完全这样做,我试图表明,如果你把焦点放在你正在使用的对象上,它会变得更清晰你的控制器动作应该放在哪里。

        您还将最好地了解 CRUD(Create R阅读 U更新 Destroy) Rails 控制器和对象的性质。标准的 Rails 控制器是这样设置的:

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-11-23
          • 1970-01-01
          • 2019-07-14
          • 1970-01-01
          相关资源
          最近更新 更多