Rails FriendlyId with URLs within URL

2019-09-16 02:47发布

问题:

My app caches web pages

On pages#new, when you submit a URL (without the http:// prefix) a page is created and you're redirected to the show, something like pages/4 where 4 is the ID

I'm trying to add friendly_id but am running into issues after adding extend FriendlyId and friendly_id :url to my Page model

If I supply "yahoo.com", the redirect goes to page/yahoo.com. yahoo.com is interpreted as {"id"=>"yahoo", "format"=>"com"} and rails tells me Couldn't find Page with id=yahoo

If I supply "yahoo.com/index.html", the redirect goes to page/yahoo.com/index.html but then I simply get No route matches [GET] "/pages/yahoo.com/index.html"

How do you think I can solve this?

回答1:

A period in a rails route denotes a format (.json, .html, .csv etc.). In order for a route to contain a period, you need to set the format option on the route to false in your config/routes.rb file.

This answer is borrowed from Disable :.format routes in rails3.

match '*pages' => 'pages#show', :format => false

Or (resourceful):

constraints :format => // do
  resources :pages
end

As for friendly_id, have you run the migrations to add the :slug column to the Page model?

For your example, friendly_id takes the :url column, makes it a friendly URL and then updates your Page instance with the correct :slug value. I suspect that friendly_id would likely replace periods with underscores but I did not verify this.

If you do not want to use the :slug column and you already have a :url column then you need to define it as such:

friendly_id :url, use: [:slugged], slug_column: :url

... specifically, the slug_column argument.