简体   繁体   中英

Dynamic Custom Routing in Rails

I don't want to use Rails routing conventions, as I want my urls to look a certain way. My model structure hierarchy is dynamic.

If I have these three paths referencing different books:

/book/chapter/page

/book/chapter/page/sentence

/book/page/sentence

Different books I'm storing in the DB (mongodb) have different hierarchies, but they all START with Book and END with Sentence, it's just the middle part that varies.

My current logic for Routes is to handle it all in a RoutesController:

Routes

get '*path', to: "routes#route"

Routes#route

def route
    path = params[:path].split("/")


    ## Look up the book
    book = Book.find_by(name: path[0])

    ## Get the book specific hierarchy, like ["books", "pages", "sentences"]
    ## or ["books", "chapters", "pages", "sentences"]
    hierarchy = book.hierarchy 


    if path.length == hierarchy.length
      ## Since end of hierarchy is always sentence
      ## Here is want to redirect_to Sentence#Show
    else
      ## Here I want to look up based on model specific hierarchy
      ## LOOKUP CONTROLLER: hierarchy[path.length-1]}", ACTION: Show
      ## eg: Chapter#show, Subchapter#show, Page#show, etc.
    end  
end

I cant do a simple redirect_to because I'm not using the config/routes file so it throws an error:

No route matches {:action=>"show", :controller=>"chapters", :path=>"books/chapters"}

I know you don't want to use the default routes, but you may be able to make them work.

scope ':bookName' do
  scope '(:chapter)', :chapter => /c\d+/ do #we need to know if it's a chapter
    scope '(:page)', :page => /p\d+/ do #or a page, c1 = chapter, p1 = page
      resources :sentence
    end
    resources :page
  end
  resources :chapter
end

The () make a part of the path optional.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM