Is it proper to have a static_pages controller whose only purpose is to render static pages in large apps? Take the following scenario for instance:
You are developing a social network application and are devising the design of the application. You know you will need to be able to route some pages, like:
a landing page (for non-logged in users) at root route
a homepage/dashboard (for logged-in users) at root route
My question is: would you define a static_pages controller to handle the landing page and, later, when an authentication system is in place, check to see if [a user is] authenticated and replace templates? Or might you go without such a controller, opting to create a users_controller with a :before_action that checks for authentication, and redirects (on failure (read: unauthenticated users)) to the aforementioned landing page?
According to the Rails tutorial by Michael Hartl, the static_pages controller would be the way to go; however, my thinking is that that tutorial is geared at very new users of the framework and, perhaps, thus doesn't use the best of conventions in the name of simplicity.
What would be the preferred way, mainly in something of a large app (like Twitter, for example, or even StackOverflow), to handle such a situation?
Yeah it doesn't really make any sense to have a static controller, unless you have something major happening on those pages, that is specific to those pages. In the end it all comes down to your personal preference in how you feel comfortable structuring your app, but in a professional environment, and in the case of Twitter or StackOverflow, they almost certainly wouldn't have static controllers. You're right in assuming that Hartl's guide is geared toward beginners and is meant to teach the basics, not the finer points and conventions. If you need to authenticate a user on a static page, Rails convention absolutely dictates that you would perform that authentication in a users_controller.
Related
Hey guys and merry christmas!
I'm new to ruby on rails and I'm still a little bit confused about some stuff:
When do I need to create a new controller and when not?
I want to create an app with a single searchbox and search through all of the articles. Should I create an Controller for the startpage (the searchbox) and for the search? Should I create controllers for the static pages?
Should I use an Admin interface gem or create my own?
The normal user should now have access to creating articles, just the admin. Should I use one of the admin interface gems or create my own?
Ruby on Rails follows the MVC framework, controllers are classes that contain your actions, so you need to add an action for every function your website will provide.
Technically you could have all actions in one controller but that would be just terrible, so we usually create different controllers to organize your routes and code in a better way.
Follow the Rails guide on controllers.
For the admin interface gem, you could use devise and cancan, they are both very reliable and well tested.
Ruby on Rails is indeed MVC, which means that controllers connect Models to Views. So in general it is good practice to think more resource-oriented: per resource you want found/presented, you create a controller. In your case something like:
ArticlesController : your main view, with the searchbox
PagesController : for static pages, if you need some erb/haml
admin/ArticlesController: for administration of the articles
Now, completely static pages can just as well be placed under the public folder, no need for a controller unless you need some dynamic info to be on the pages (e.g. a total count of articles).
With regards to your search-box: imho this is just a parameter for your index page. E.g. on the index you show the ten most recent articles, and when searching on some term, you show the relevant articles, but on the same controller and the same action.
With regards to the admin interface: yes, use gems like rails_admin or active_admin and it will get you started in no time at all. So definitely do that. But those gems are, of course, very general and might not suit your needs completely. It that should be the case, you can always easily revert later.
HTH.
Merry christmas!
As Khaled suggested Rails being MVC architecture it is always good to have controllers of each page. Even though you might have a static pages for now, but latter when you are trying to make the site dynamic one, then you will be in whole lot confusion of where to add a method for a particular view page.
Generally it is better to use a gem instead of making it from scratch.
You can look into this link which teaches you how to use devise and cancan with twitter bootstrap(for views). But if you are planning to learn rails then I better recommend you to do it from scratch as you will have an idea of what is happening. You can see this tutorial which does most of the task through scratch.
Enjoy Rails!!
I have a Rails app that I need to put access control on. (Some pages can be accessed by everyone, some pages can only be accessed by certain LDAP groups of people, etc.) What's the best way to handle this access control?
One way is to have a before_filter in all of my controllers that checks, for each action, whether the user belongs to an LDAP group authorized for that action. (But this seems possibly messy.) Is there a better way?
You should do this kind of thing with a authorization mechanism.
CanCan is really popular, and also quite simple: https://github.com/ryanb/cancan
You can find other gems for handling authorization here: https://www.ruby-toolbox.com/categories/rails_authorization
I highly recommend reading this book if you're new to Ruby On Rails. The section that talks about exactly what you need is here.
As far as I know, the before filter works perfectly, and isn't messy because it's handled in the controller for the page.
I'm developing a website but want a "Coming soon" page to be up for now. How do I structure a "Coming soon" page in my rails app 3.1? What's the best way to go about doing it.
Four options I'm considering are:
Have a static coming soon page in the public directory. Have rails routes point to it and then modify my routes file when I go live.
Have a page served by a controller pointing to www.myproject.com/home. I'll just change the routes file when I'm ready to go live to www.myproject.com
Use LaunchRock.com. Have my domain posted to LaunchRock and then point it to my site when I'm ready.
Use https://github.com/vinsol/Launching-Soon/
Which method is best suited for my Rails project?
Thank you
Any of these have different pros and cons. It's up to you really.
If you're close to launch, you'll have to set up a web-server and Rails anyhow, so either setting up a Rails controller for serving the static pages, or have a static page in your public directory, are probably the best choices then.
Personally I'd not serve the "coming soon" page through other sites/services.
One reason for having some sort of "coming soon" page is for SEO purposes. For that it's best to have full control over your site / page.
I'd go for using a Controller for the static pages, because you can more easily use the same layout as your site, and you can add dynamic content to that page (e.g. a sign-up or a contact form).
See:
http://railscasts.com/episodes/117-semi-static-pages
Option number 6) serve the static page through Rack
http://railscasts.com/episodes/222-rack-in-rails-3
Any of the above, and one more:
5.Have you webserver return a static page for all requests, bypassing rails completely.
Which one you use depends on how much trouble you want to go to, and whether you want some sort of basic app functionality (like announcements).
I suggest you make a list of what features you actually need, or are sure you'll use, and see how that matches with your list.
One thing to take into account is the time-frame. If the 'launching soon' is not going to be that soon then you'll want some way to easily keep people informed.
Put a static page with some copy up today for SEO purposes. Then consider your marketing objectives and think about what kind of features you need (e.g. mailing list signup, window into application data, viral video, etc). Balance the needs of those features against time taken away from actual development.
At the end you ask the right question (emphasis mine):
Which method is best suited for my Rails project?
But you don't give any context. Any of the methods you mentioned could be appropriate, but they are meaningless without understanding the business goals. A technical forum such as this is probably not the best place to ask at this stage.
I'm learning RoR, I've read some tutorials (railstutorial for the first one),
but I've a problem to define the logic layout of the my first simple website.
The structure is:
When you go to mysite.com you see a welcome page with the signup form or the link for login.
If you signup or you login into the site, you are at mysite.com/dashboard and you see a list of your messages.
You can go to mysite.com/$username and you see a page with a form where you can write a message for the $username.
Stop. That's it. It's very simple, I know, but is for learning.
The problem is this: I'm new to MVC paradigm and I don't know how structure the logic layout of my app. Of course there'll two models: User and Message. But for controllers? And which functions in any controllers? Should I use scaffolding?
Please give me a help, I'm very confused.
Thank you.
Controllers are the logic for the data, so to login/sign-up is really validating/creating a user, if you need to view the users dash board, well that's a look up on the user data so he goes there as well.
The messages, that will be a separate controller that can create/view messages!
As others have pointed out, your controllers contain the logic for your code and invoke views based on that logic by rendering or redirecting to pages. You can define whatever actions you want in your controllers, and then use routes to map a particular URL to a controller action. That being said, Rails gets a lot easier if you "go with the flow" and make some simple assumptions about the actions that could happen. Both your users and your messages represent rows in their respective database tables. There's no much you can do to a row in a database table - you can Create it, Read it, Update it, or Delete it (CRUD). If you define your actions in terms of these four logical actions, Rails lets you generate some easy routes.
You can back into any URL schema that you want, but what you are describing is:
Read the messages that are for a user on the dashboard
Create a message for a user when you go to another page (mysite/username)
Each of these maps to a CRUD action that you should be defining in your controllers.
Agreed also with other advice to simply do a few more tutorials that will probably clear this up.
If you haven't already, read Getting Started with Rails. Look out for the discussion on MVC and scaffolding. Playing around with scaffolding can help you learn where things go and is a great place to start for beginners.
Also, I highly recommend this book: Agile Web Development with Rails. It is very hands on and an easy read.
I have models A,B,C,D, etc. I have my usual controllers/views/helpers for each of these models. These are accessed by a set of content authors in a form based application to populate data into the db. The content authors will also have categories like authors, publishers, super admins etc. Essentially we have built out a mini content management system.
A set of other users (unrelated to the above set) need to access data in some of these models. But the view for those are totally different. I also do not want these users to have the edit screens for the models they are allowed to view. Essentially these guys are end users who use the application as a read only/analytics data store.
How do I accomplish this? Should I create separate controllers and invoke these models for the user website? How do I ensure the website users do not have access to the cms screens? Any pointers, design principles, routing methods, gems for such an application?
How do I accomplish this? Should I create separate controllers and invoke these models for the user website?
I would create a different set of controllers for the backend and frontend. I would move the backend controller to a namespace. More Information on namespaces: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing
How do I ensure the website users do not have access to the cms screens? Any pointers, design principles, routing methods, gems for such an application?
For this you need some kind of authentication and authorization. Some examples:
authentication:
authlogic
devise
authorization:
cancan
declarative_authorization
aegis
acl9
There are some good screencasts on this matter:
Authlogic
Declarative Authorization
Authorization with CanCan
Introducing Devise
Customizing Devise
You need a layer of authentication.
The easiest way, and I'd say the most common one is to make separate controllers for each section, and add a before_filter method in each section authenticating and authorizing user to continue (usually a is_admin? method on the user model), or redirect back with an error message if the user is not allowed.
You can separate your controllers with namespaces (something like /admin/authors, /admin/books/1/edit and so on), and keep them RESTful this way.
If you need a more complex schema, you can use any of the authorization tools out there http://ruby-toolbox.com/categories/rails_authorization.html