Ruby on Rails 中的欢迎/主页-最佳实践

我的主页(或欢迎页面)将包含来自两个模型的数据(让我们称之为作者和文章)。我是新来的,不知道什么是最好的方式来实现这一点。

我是否应该创建一个名为 Welcome 的新控制器,该控制器从作者和文章中收集数据,然后将它们显示在欢迎索引视图中?或者我应该在帖子模型下有一个受欢迎的视图,它也可以从作者那里获得数据?或者其他的方法?

我知道如何在技术上做到这一点,但只是不确定使用 Rail 框架的最佳实践方法是什么。

66033 次浏览

Create a new controller named as appropriately as you can. SummaryController? StartController? DailyFrontPageController? You'll have an idea.

Not only that, I'd seriously consider creating a new Model, not ActiveRecord-based, that collects the information from your Author and Post models (or whatever their real names are) for presentation in your view. The alternative is to assemble the data in the controller, which will almost certainly be messy - it was every time I tried it, and I tried it a lot. A separate model seems to end up a lot tidier.

If the processing is relatively straightforward, why not try building the data in the controller first, then wrap the output in a Struct, then replace the Struct with a real class and move the construction there, refactoring all the way. It shouldn't add too much to the total time (most of the code can be reused) and you'll get a good idea of what works best for you.

The question is, is your home page just a landing page or will it be a group of pages? If it's just a landing page, you don't expect your users to hang around there for long except to go elsewhere. If it's a group of pages, or similar to an existing group, you can add an action to the controller it's most like.

What I've done for my current project is make a controller named Static, because I need 3 static pages. The home page is one of these, because there isn't anything to see or do except go elsewhere.

To map a default route, use the following in routes.rb:

# Place at the end of the routing!
map.root :controller => 'MyController', :action => :index

In my case this would be:

map.root :controller => 'static', :action => :index

If you wish to, you could create a controller just for this home page. I'd call it main, or something that you can remember which relates to the home page. From there you can get your data and your models and defer to the output view.

class MainController < ApplicationController
def index
@posts = Posts.find(:all, :limit => 10, :order => 'date_posted', :include => :user)
end
end

Assuming you have your model relationships defined correctly, the template to match it will be very simple.

Good luck, hope this helps.

The best practice would be your first suggestion. Create a 'welcome' controller and call the records from whichever models you want. Have a root route point to that controller. Very clean and proper.

I asked myself something like this when I first started Rails. Here's what you need to know:

  • Models are not necessarily directly related to controllers and views.

That is, a particular controller/view combination can work with as many models as you need to generate that particular page.

The purpose of the controller is to prepare the dataset you need to display, irrespective of what models are used to store that data.

The purpose of the view is to then display that data in the most appropriate way.

In other words, controller/view combinations are never 'under' a particular model. They use models, but are not under them in any hierarchical relationship. In fact, they are peers to whatever models they use.

I think the confusion comes from the scaffold generator example found in AWDR and other introductory texts, like:

ruby script/generate scaffold model controller

I know that this implied relationship between model and controller/views confused me for a bit. But there is no strict relationship, really. If there were, then it would be very difficult to do anything complicated with the MVC approach. And clearly, that is not the case.

Hope this helps.

-- John

Please note that in Rails3, correct way to handle this is to add following line to the end of the routes.rb file:

root :to => "welcome#index"

and delete public/index.html.erb.

Please also note that welcome#index corresponds to index action in a WelcomeController and the code from The Wicked Flea's answer would look like:

class WelcomeController < ApplicationController
def index
@posts = Posts.find(:all, :limit => 10, :order => 'date_posted', :include => :user)
end
end

There doesn't seem to be a single best practice.

(1) The standard config/routes.rb file seems to suggest that the root page (or home/welcome page) should be handled by welcome#index. If you were to be guided by that, then to generate the corresponding welcome#index controller/action, you can use the following command:

rails generate controller Welcome index

Then, in config/routes.rb, you can remove the GET route (get "welcome/index") automatically added by the generator, and place the root route root 'welcome#index' (or root :to => 'welcome#index' in Rails < 4) at the top of the file, because it will probably be your most popular route and should be matched first.

Also remember to delete public/index.html in Rails < 4.

(2) The official Ruby on Rails routing guide uses PagesController. It actually suggests pages#main, though to me it makes more sense to go with pages#home (because "homepage" is the ubiquitous term/concept). Additionally, this controller can handle other page-oriented actions such as pages#about, pages#contact, pages#terms, pages#privacy, etc.

(3) The Ruby on Rails Tutorial, goes with static_pages#home and static_pages#help, etc., though I don't like the idea of denoting this controller with "static". These pages will still likely have some dynamic aspects to them, particularly the homepage!

(4) Though it does not discuss how to handle a homepage, RailsCast #117 on Semi-Static Pages suggests yet another set of approaches to show-only resources.

I feel preference toward 1 and/or 2. With the "and" scenario, you could use welcome#index and pages#about, etc., whereas with the "or" scenario, you could use pages#home, pages#about, etc. If forced to choose, I would go with option 2 just because you end up with less code. And btw, 2 and 3 are pretty much the same, apart from the word "static".

This answer is as of Rails 3.2.1.

First set up a Controller for pages, named for example static:

$ rails generate controller static

In file app/controllers/static_controller.rb:

class StaticController < ApplicationController
def index
end
end

Create the new View file app/views/index.html.erb

And finally configure your config/routes.rb:

MyApp::Application.routes.draw do
match 'home', :to => "static#index"
root :to => "static#index"
end

This will make both /home and / go to whatever you put in the View file you just created.