rsnyder
rsnyder

Reputation: 395

Accessing specific pages in a controller/view on Rails App

I am trying to set individual Meta Descriptions and Titles to individual pages in a Ruby on Rails App. It was a previous developers App, that I have been given the task to edit. Also, I am new to Rails and Ruby.

The app has a controllers/pages_controller.rb where I was am able to set unique variables for @descriptionX and @title on some pages (mission and disclaimer), but not for others, such as 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

I think that the render params[:page] is where I am getting lost. I'm not 100% sure of what this is doing, or how to use it.

I don't understand why I would be able to control the @title and @description of mission but not pet_planning when their views are both in the same /views/pages/ directory. And I can't seem to find any distinction between the two anywhere else in the app.

Also, tried to add = @title = 'Pet Planning' in the /views/pages/pet_planning.html.haml file. It does change the title, however it also displays at the top of the page content unexpectedly.

Any help would be appreciate. Thanks.

Upvotes: 0

Views: 312

Answers (2)

Andrew Haines
Andrew Haines

Reputation: 6644

I'd recommend having a read of the ActionController guide, which explains how Rails turns a request from the user into a page to render.

Basically, when you send a request, for example

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

then Rails works out what to do with it using the router (the routing guide explains this in more detail). I would imagine that your app is set up so that the /pages route matches to the PagesController#index action. You can have a look in your config/routes.rb file and/or type rake routes at the terminal to see how your routes are set up.

The bit after the question mark in the request is the "query string", and Rails turns this into a params hash which, for my example above, would look like {:page => "pet_planning"}. Your index action looks at that to get the name of the page to render - that's what render params[:page] is doing.

I guess that the reason you can modify the variables for some of your pages and not others is that some of them have their own routes - /pages/mission uses the PagesController#mission action, for example - while certain pages are accessed via the index action using the page param - /pages/?page=pet_planning or possibly /pages/index.html?page=pet_planning.

Update: Your existing route

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

could be broken up into

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

which would correspond to a controller that looks like this

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

Your suggestion is close, but because the route format is "controller_name#action_name", you would require multiple controllers that looked like this

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

and you would have to move your views from app/views/pages/pet_planning.html.haml to app/views/pet_planning/index.html.haml. So it's probably not quite what you want.

Note that there might be a better way to tackle the problem than splitting everything up into separate actions, if all you are doing differently in each one is customising the title and description. For example, you could use a hash that maps your page name to its corresponding information:

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

Upvotes: 1

Marlin Pierce
Marlin Pierce

Reputation: 10079

The render calls in pet_planning, mission, and disclaimer do the same as default behavior, so those calls can be removed. They are telling rails to use the pages with the given file names. For the index method, this is rendering a page based on a parameter.

The title and description are likely set in the layout. Look in /views/layouts/application.html.haml or /views/layouts/pages.html.haml.

Upvotes: 0

Related Questions