I am using the Ancestry Gem in my Rails 5 app and all things look and act as they should and my database looks good. I just can't figure out out how to show the full url path after the first level following the model name.
For Example
I need http://127.0.0.1:3000/pages/29
to look like http://127.0.0.1:3000/pages/22/29
(I'll implement friendly ids after its working). In the above example, id:29
is a subpage of ancestry id:22
Screenshot of Database
page.rb
class Page < ApplicationRecord
has_ancestry
end
pages_controller.rb
...
private
...
def page_params
params.require(:page).permit(:name, :content, :ancestry, :slug, :parent_id)
end
...
schema.rb
create_table "pages", force: :cascade do |t|
t.string "name"
t.text "content"
t.string "ancestry"
t.string "slug"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["ancestry"], name: "index_pages_on_ancestry"
end
routes.rb
...
resources :pages
root to: 'pages#index'
...
127.0.0.1:3000/rails/info/routes
Helper HTTP Verb Path Controller#Action
Path / Url
Path Match
stripe_event_path /webhooks/stripe
StripeEvent::Engine
new_user_session_path GET /users/sign_in(.:format)
devise/sessions#new
user_session_path POST /users/sign_in(.:format)
devise/sessions#create
destroy_user_session_path DELETE /users/sign_out(.:format)
devise/sessions#destroy
new_user_password_path GET /users/password/new(.:format)
devise/passwords#new
edit_user_password_path GET /users/password/edit(.:format)
devise/passwords#edit
user_password_path PATCH /users/password(.:format)
devise/passwords#update
PUT /users/password(.:format)
devise/passwords#update
POST /users/password(.:format)
devise/passwords#create
cancel_user_registration_path GET /users/cancel(.:format)
devise/registrations#cancel
new_user_registration_path GET /users/sign_up(.:format)
devise/registrations#new
edit_user_registration_path GET /users/edit(.:format)
devise/registrations#edit
user_registration_path PATCH /users(.:format)
devise/registrations#update
PUT /users(.:format)
devise/registrations#update
DELETE /users(.:format)
devise/registrations#destroy
POST /users(.:format)
devise/registrations#create
users_path GET /users(.:format)
users#index
POST /users(.:format)
users#create
new_user_path GET /users/new(.:format)
users#new
edit_user_path GET /users/:id/edit(.:format)
users#edit
user_path GET /users/:id(.:format)
users#show
PATCH /users/:id(.:format)
users#update
PUT /users/:id(.:format)
users#update
DELETE /users/:id(.:format)
users#destroy
pages_path GET /pages(.:format)
pages#index
POST /pages(.:format)
pages#create
new_page_path GET /pages/new(.:format)
pages#new
edit_page_path GET /pages/:id/edit(.:format)
pages#edit
page_path GET /pages/:id(.:format)
pages#show
PATCH /pages/:id(.:format)
pages#update
PUT /pages/:id(.:format)
pages#update
DELETE /pages/:id(.:format)
pages#destroy
root_path GET /
pages#index
Routes for StripeEvent::Engine
root_path POST /
stripe_event/webhook#event
You want to perform a GET
request /pages/:anchestry_id/:id
for action pages#show
You need to add a special route at the top of your routes.rb
file
get '/pages/:anchestry_id/:id' => 'pages#show', as: 'page'
You need to understand where you want to have that link, so from which pages in your app you want to call the action pages#show
, because you will need to go to that controller action and in that action retrieve the 2 variables required for that link, which are @anchestry
and @page
If you are doing this from the pages#index
, then you will have many links and you will have to query all the @ancestries
and @pages
then loop them in the view to create many links
pages_controller.rb
def index
@ancestries = Ancestry.all
@pages = Page.all
end
Then you need to add a link in the pages
<%= link_to 'page', page_path(@ancestry, @page) %>
Or in the case of the pages/index.html.erb
, which will use @pages
and @ancestries
do
<% @pages.each do |page| %>
<%= link_to 'page', page_path(page.ancestry, page) %>
<% end %>
the problem is that as I see from your db, some entries have the ancestry as nil
31 About us Description of company [Null]
this will trigger a routes error, because you will be passing page.ancestry = nil
and you can not have a route /pages/null/31
So I believe you need to put your thought back together and think about the design of your app architecture.
Also why passing the ancestry
in your route?
All this does not make sense