I'm trying to implement semi-static pages as per this railscast
At first I named my class 'About', but that threw the following error:
Invalid route name, already in use: 'page' (ArgumentError)
You may have defined two routes with the same name using the :as option, or you may be overriding a route already defined by a resource with the same naming.
After some googleing, it seemed like it was conflicted with active_admin for some reason, so I rename the table to 'Page' and I've carefully renamed all the appropriate files, classes and methods etc. from 'About' to 'Page'
This is my Page model:
class Page < ActiveRecord::Base
validates_uniqueness_of :url
def to_param
url
end
end
And these are my routes:
get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'
devise_for :admin_users, ActiveAdmin::Devise.config
ActiveAdmin.routes(self)
resources :users
resources :sessions
resources :password_resets
resources :posts do
resources :comments
resources :votes, only: [:new, :create]
resources :flags, only: [:new, :create]
end
resources :comments do
resources :comments
resources :votes, only: [:new, :create]
resources :flags, only: [:new, :create]
end
resources :newsletters
resources :pages, except: :show
resources :subscribers, only: [:index, :new, :create]
# resources :prelaunch
# get 'about', to: 'prelaunch#about'
root to: 'posts#index'
get ':id', to: 'pages#show', as: :page
I'm still getting the same error as described above.
The only way I can get it to half-work is by dropping the 'as: :page' bit, which stops the conflict, and hardcoding the url I want to point to into the code e.g.
<%= link_to page.name, "localhost:3000/#{page.url}" %>
which is far from ideal.
I can't find any help in Routing from the Outside In.
Could anyone help?
Here's the fix:
#config/routes.rb
resources :pages, except: :show
(remove get ':id', to: 'pages#show', as: :page)
This will create the standard RESTful routes, which will create a routing structure except the show action
Slugs
How to create app-wide slug routing for Rails app?
If you want to have /about etc, you'll have to generate them specifically:
#config/routes.rb
if Page.all.any?
Page.all.each do |page|
get page, to: "pages#show", id: page.id
end
end
This can also be handled with friendly_id
Have you considered using a gem that "does the work for you"? I've been using the https://github.com/thoughtbot/high_voltage gem to take care of static pages for me, without any hassle. It takes care of both routing and controller, only leaving the creation of the pages in a dedicated view/pages folder. Linking to a static page is as simple as creating a link to page_path(:name_of_the_page)
Ok, after a lot of hacking around and a helpful pointer from Rich Peck, I've got a working solution.
Routes:
resources :pages, except: :show
if Page.all.any?
Page.all.each do |page|
get "#{page.url}", to: "pages#show", as: "#{page.url}", id: page.id
end
end
Controller:
def show
#page = Page.find(params[:id])
end
Note, I've used the friendly_id gem as suggested.
To dynamically generate links:
Application controller:
def about_us
#pages = Page.all
end
helper_method :about_us
Pages helper:
def about_link(page)
link_to page.name, "/#{page.url}"
end
NB: - you need to include the / otherwise it will try to prepend the name of the controller for the page you're on (I'm not sure why).
My footer:
<% about_us.each do | page | %>
<%= about_link(page) %>
<% end %>
UPDATE:
I've had a lot of trouble deploying my app to Heroku, and I believe it's because of the pages routes.
I've now changed to a much simpler solution:
resources :pages, path: ""
and the problem's have gone away.
Related
I'm actually having trouble finding the documentation for this so if you have a link handy that would be really appreciated too.
So I have:
resources :users do
resources :posts, only: [:index, :create, :show]
end
I wanted to access the index action of posts through a named route. I tried this: <%= link_to 'User Posts', user_posts_path %> but it said it was missing user_id. Any ideas?
When using the nested resource routes, you would need to provide the reference id of the parent resource. In your case resource user. You could do: user_posts_path(user). The route generated would be something like: /users/1/posts where 1 is the :user_id or if you would rather want a route like: /users/posts you should do:
resources :users do
collection do
resources :posts
end
end
Find full routing documentation here
it's asking for user_id because you're defining :users as a resource, change it for a namespace instead:
namespace :users do
resources :posts, only: [:index, :create, :show]
end
IN the first few lines is where i made the changes. Is there a way I can post the project so i can give the most information possible?
also i am not using the users controller/file at all. Does authorization require me to use the USer scaffold, because i am using the Newuser scaffold.
Cms::Application.routes.draw do
root :to => "home#merchant"
controller :sessions do
get 'login' => :new
post 'login' => :create
delete 'logout' => :destroy
end
resources :newusers
resources :users
resources :maintenances
resources :leases
resources :sales
resources :saleterminals
resources :salesreps
resources :terminaltypes
resources :processings
resources :manufacturers
resources :promotions
get "community/index"
resources :currents
resources :merchants
get "home/index"
get "home/about"
get "home/contact"
get "home/processing101"
get "home/terminaloptions"
get "home/weekend"
get "home/conditionsofuse"
get "home/privacypolicy"
get "home/announcements"
get "home/support"
get "home/sitemap"
get "home/search"
post "home/search"
end
Routes
A piece of advice - you can DRY up your routes by declaring multiple resources sequentially like so:
#config/routes.rb
Cms::Application.routes.draw do
root to: "home#show", id: "merchant"
controller :sessions do
get 'login' => :new
post 'login' => :create
delete 'logout' => :destroy
end
resources :newusers, :users, :maintenances, :leases, :sales, :saleterminals, :salesreps, :terminaltypes, :processings, :manufacturers, :promotions, :currents, :merchants
resources :community, only: :index
resources :home, only: [:index, :show] do
collection do
post :search
end
end
end
Something to note is I moved your entire home actions to send to the show action. Reason being if you want to show individual pages, you'll just need a show action like so:
#app/controllers/home_controller.rb
Class HomeController < ActiveRecord::Base
def show
render "home##{params[:id]}"
end
end
Authentication vs Authorization
Authentication is whether someone is a user or not
Authorization is whether that user has permission to do
certain things or not
If you're looking to authenticate the user, you may be better suited to using a gem called Devise, which handles the entire authentication process, from signup to sessions. There is a Railscast about this here
--
Fix
In reference to your issue, if you want to show projects information, why don't you just have a projects controller with the only actions as index and show:
#config/routes.rb
resources :projects, only: [:index, :show]
If you want to then allow users to upload or change projects, you can use an "admin" area of sorts, like this:
#config/routes.rb
namespace :admin do
resources :projects, except: :index #-> /admin/projects/new
end
I changed the routing of posts#index to match blog and I now get /blog in the URL which I was trying to accomplish.
I've tried several different things to get my actual blog post which the route currently looks something like /posts/this-is-a-test to also use blog rather than posts in the URL.
Below is my current route file. I am using the friendly_id gem, if that makes any difference in answering this question.
resources :posts do
resources :comments
end
resources :contacts, only: [:new, :create]
root "pages#home"
get "/home", to: "pages#home", as: "home"
get "about" => 'pages#about'
get "pricing" => 'pages#pricing'
get "contact_us" => 'pages#contact_us'
match 'blog', to: 'posts#index', via: :all
end
path option along with resource must help.
resources :posts, :path => 'blogs' do
resources :comments
end
This will change all /posts and /post to /blogs/ and /blog.
If you want to change your route's helper methods such as posts_path to blogs_path and new_post_path to new_blog_path etc, you can change it with as tag.
resources :posts, :path => 'blogs', :as => 'blogs' do
resources :comments
end
Or yet better, you can specify the controller and route blogs directly as:
resources :blogs, controller: 'posts' do
resources :comments
end
This is the awesomeness of Rails! :)
match 'blog/:id' => 'posts#show'
should work. But if you want to match every method in posts controller to blog (and you don't want to use the posts path), I would just rename the controller to blog instead and add resource :blog in the routes.
This helped me, from official guides documentation, add this in your routes.rb file:
get '/patients/:id', to: 'patients#show', as: 'patient'
I am using Rails 3.2
I want to have routing pretty much exactly like github, so:
root/(username)
root/(username)/(projectname)
root/(username)/(projectname)/issus
etc.
I am trying something like this:
resources :publishers do
resources :magazines do
resources :photos
end
end
But that gives routes like this:
/publishers/1/magazines/2/photos/3
A project I am looking at does the following which seems to work but does not seem to be for me.
resources :projects, :constraints => { :id => /[^\/]+/ }, :except => [:new, :create, :index], :path => "/" do
member do
get "team"
get "wall"
get "graph"
get "files"
end
resources :wikis, :only => [:show, :edit, :destroy, :create] do
member do
get "history"
end
end
If you want to get rid of the id number (which is rails default) and use a name I suggest the FriendlyId gem.
watch this railscast http://railscasts.com/episodes/314-pretty-urls-with-friendlyid
and here is the github page https://github.com/norman/friendly_id
EDIT
This is the article I was looking for, I forgot I bookmarked it months ago.
http://jasoncodes.com/posts/rails-3-nested-resource-slugs
You must to use friendly_id and scope
scope '/:username/:projectname', module: 'users/projects', as: 'users_project' do
resources :issus
resources :photos
end
I'm trying to define a route in routes.rb and I can't do anything from this Ruby on Rails routing guide that will let this error pass.
No route matches {:controller=>"devise/home"}
Here's my routes.rb source.
SchoolCMS::Application.routes.draw do
root :to => "home#index"
devise_for :teachers, :admin
resources :home, :only => :index
resources :admin, :only => :index
resources :events do
resources :event
end
resources :posts do
resources :comments
end
end
Just to be safe I would remove devise_for :teachers, :admin and split it so that it is
devise_for :teachers
devise_for :admin
I'm not sure you can specify multiple devises the way you use it, see if this fixes your error.
Also try to use path helpers were possible so instead of doing <%= link_to 'Home', :controller => 'home' %> make it <%= link_to 'Home', homes_path %> but make sure you define your home as resource :home, :only => :show since it's a singular resource.