【问题标题】:Accessing specific pages in a controller/view on Rails App在 Rails 应用程序的控制器/视图中访问特定页面
【发布时间】:2013-01-09 03:10:54
【问题描述】:

我正在尝试为 Ruby on Rails 应用程序中的各个页面设置单独的元描述和标题。这是以前的开发人员应用程序,我被赋予了编辑任务。另外,我是 Rails 和 Ruby 的新手。

该应用程序有一个controllers/pages_controller.rb,我可以在其中为某些页面(任务和免责声明)上的@descriptionX@title 设置唯一变量,但不能为其他页面设置唯一变量,例如pet_planning。

class PagesController < ApplicationController
  def index
    @title = params[:page].humanize
    render params[:page]
  end

  def pet_planning
    @descriptionX = 'pet planning'
    @title = 'pet planning title'
    render :pet_planning
  end        

  def mission
    @title = 'Our Mission Statement'
    @descriptionX = 'Mission Description'
    render :mission
  end

  def disclaimer
    @title = 'Our Disclaimer'
    render :disclaimer
  end

end

我认为render params[:page] 是我迷路的地方。我不是 100% 确定这是做什么的,或者如何使用它。

我不明白为什么当views 都在同一个/views/pages/ 目录中时,我可以控制mission@title@description 而不是pet_planning。而且我似乎在应用程序的其他任何地方都找不到两者之间的任何区别。

另外,尝试在/views/pages/pet_planning.html.haml 文件中添加= @title = 'Pet Planning'。它确实改变了标题,但它也意外地显示在页面内容的顶部。

任何帮助将不胜感激。谢谢。

【问题讨论】:

  • 澄清一下。我能够控制大多数页面的@title@description。除了/views/pages/ 目录中的少数几个。但是为什么missiondisclaimer也在上述目录中时我可以控制它们呢?
  • render params[:page] 允许攻击者执行任意代码(除非此处未显示清理)

标签: ruby-on-rails ruby controller


【解决方案1】:

我建议阅读 ActionController guide,它解释了 Rails 如何将来自用户的请求转换为要呈现的页面。

基本上,例如,当您发送请求时

GET http://www.example.com/pages/?page=pet_planning

然后 Rails 使用路由器计算出如何处理它(routing guide 对此进行了更详细的解释)。我想您的应用程序已设置为使 /pages 路由与 PagesController#index 操作匹配。您可以查看您的 config/routes.rb 文件和/或在终端输入 rake routes 以查看您的路线是如何设置的。

请求中问号后面的位是“查询字符串”,Rails 将其转换为params 哈希,对于我上面的示例,它看起来像{:page =&gt; "pet_planning"}。您的 index 操作会查看它以获取要呈现的页面的名称 - 这就是 render params[:page] 正在做的事情。

我猜您可以修改某些页面而不是其他页面的变量的原因是它们中的一些有自己的路由 - 例如,/pages/mission 使用 PagesController#mission 操作 - 而某些页面通过以下方式访问index 操作使用 page 参数 - /pages/?page=pet_planning 或可能是 /pages/index.html?page=pet_planning

更新:您现有的路线

match 'practice_areas/:page' => 'pages#index', :as => :pages

可以分解成

match 'practice_areas/pet_planning' => 'pages#pet_planning' :as => :pet_planning
# etc ...

这将对应一个看起来像这样的控制器

class PagesController < ApplicationController
  def pet_planning
    @title = "Pet planning!"
    @description = "Whatever..."
  end
end

您的建议很接近,但因为路由格式是"controller_name#action_name",您需要多个看起来像这样的控制器

class PetPlanningController < ApplicationController
  def index
    @title = "Pet planning!"
    @description = "..."
  end
end

您必须将视图从app/views/pages/pet_planning.html.haml 移动到app/views/pet_planning/index.html.haml。所以这可能不是你想要的。

请注意,如果您在每个操作中的不同之处在于自定义标题和描述,那么解决问题的方法可能比将所有内容拆分为单独的操作更好。例如,您可以使用将您的页面名称映射到其相应信息的哈希:

class PagesController < ApplicationController
  PAGE_INFO = {
    "pet_planning" => ["Pet planning!", "Whatever..."],
    "other_page" => ["Title", "Description"],
    # ...
  }

  def index
    page_name = params[:page]
    @title, @description = PAGE_INFO[page_name]
    render page_name 
  end
end

【讨论】:

  • 您对路线的看法是正确的,我通读了这两个文件,但仍然遇到了一些问题。在我的routes.rb 文件中,我找到了match 'practice_areas/:page' =&gt; 'pages#index', :as =&gt; :pagesmatch 'mission' =&gt; 'pages#mission', :as =&gt; :mission 所以我不应该能够将第一行分解为match 'practice_areas/pet_planning' =&gt; 'pet_planning#index', :as =&gt; :pet_planning match 'practice_areas/pet_planning2' =&gt; 'pet_planning2#index', :as =&gt; :pet_planning2 等吗?
  • 是的,你在正确的轨道上。请参阅我编辑的答案以获取正确的路线。另请注意,可能有更好的方法,我在底部添加了一个建议:)
【解决方案2】:

pet_planning、mission 和 disclaimer 中的渲染调用与默认行为相同,因此可以删除这些调用。他们告诉 Rails 使用具有给定文件名的页面。对于 index 方法,这是根据参数渲染页面。

标题和描述可能在布局中设置。查看 /views/layouts/application.html.haml 或 /views/layouts/pages.html.haml。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-05
    • 1970-01-01
    相关资源
    最近更新 更多