I want to be able in browsing bar see full path to some product. The path would look like this
www.mysite.com/categories/category_name/subcategory_name/product_name
At this moment I have just
www.mysite.com/categories/category_name
It just provides with one level path, that I don't need.
To build these friendly links I used friendly_id. And full categorization function I created using gem called Ancestry.
How can I modify friendly_id slug so that I can show the full path? I know how the friendly_id works, but I don't know how to change the way how slug is generated.
Some guys could just give me link or tip to search for. I can work it out, I just need idea.
I would be very greatfull :) :)
You can pass a method for the gem to use, as in:
extend FriendlyId
friendly_id :method_name, use: :slugged
def method_name
end
You're probably looking for nested resouces.
If both models (category, subcategory) have slugs, nesting them in your routes.rb file should do the trick:
resources :categories do
resources :subcategories
end
Related
I'm wondering how to generate a url that includes friendly ids for two different models. For example, if you have a post titled 'Rails Tutorial' and belonging to a particular User named 'Michael', and they each use a slug in place of their ID, how would you generate a url that looks like site.com/michael/rails-tutorial.
If you set your route to be:
get ':id/:id' => 'posts#show', as: 'show_post'
the URL will either be michael/michael or rails-tutorial/rails-tutorial, yet the way Friendly_id works from what I know is that your slug is represented by :id, so you can't configure it to work with get ':user_id/:post_id'.
I'm sure I just don't understand FriendlyID enough. Any help is appreciated.
In order to get the url you’re looking for, you’ll need to nest your routes:
resources :users do
resources :posts
end
This will give you the route:
localhost:3000/users/slug/post/slug
You’ll also have to extend FriendlyId in each model, add the slug to each model in a migration and use .friendly in the controller action(s).
I'd like to create a slug based on the ancestors of the record. If I already have a slug created. The best solution I have come up with is:
def pretty_url
path.select(:slug).map(&:slug).join("-")
end
Is there a more precise way to do this using the ancestry gem?
Also, I am using friendly id to generate the slug, so maybe there is a better way using friendly id?
This is what I figured out, using friendly id and ancestry gem together.
friendly_id :slug_candidates, use: :slugged
def slug_candidates
[
[parent.try(:slug), :title]
]
end
I'm currently using friendly_id gem in rails and noticed that if someone names a post "About" that it overwrites the /about path that I have assigned to a static page in my routes.rb file.
This is my current code:
extend FriendlyId
friendly_id :title, use: :history
If there are prior posts with the same name...it adds a --2. But friendly_id seems to ignore static routes in my routes.rb.
Is there a way to make friendly_id recognize and not overwrite these routes?
Thank you
FriendlyID includes a Reserved module which prevents a list of provided words from being used as friendly slugs. You could add your static routes to the reserved words array which would prevent someone from overwriting your routes.
From the FriendlyId RDocs
FriendlyId.defaults do |config|
config.use :reserved
# Reserve words for English and Spanish URLs
config.reserved_words = %w(new edit nueva nuevo editar)
end
If you still want to allow for a title that is reserved you can make a new method that FriendlyId would use for the slug. This piece from the RDocs explains that
Column or Method?
FriendlyId always uses a method as the basis of the slug text - not a column. It first glance, this may sound confusing, but remember that Active Record provides methods for each column in a model's associated table, and that's what FriendlyId uses.
Here's an example of a class that uses a custom method to generate the slug:
class Person < ActiveRecord::Base
friendly_id :name_and_location
def name_and_location
"#{name} from #{location}"
end
end
bob = Person.create! :name => "Bob Smith", :location => "New York City"
bob.friendly_id #=> "bob-smith-from-new-york-city"
You could create a method like :title_with_id or :title_with_rand. it's up to you and how you'd like the slugs to look.
You would also want to make sure your routes.rb has your static routes listed prior to the routes for with the friendly id. The first route dispatcher matches is where the request will be processed.
My task is to be able to see the path of the current category or product in browsing bar.
At this moment I just can see current category like this
localhost:3000/categories/smalcinataji
but I want like this
localhost:3000/categories/atkritumu-parstrades-tehnika/smalcinataji
To create pretty urls I am using gem called FriendlyId from this example http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=asciicast
Thanks!
FriendlyId can take a method to construct the slug.
class Person < ActiveRecord::Base
friendly_id :category_and_subcategory
def category_and_subcategory
"#{my_category_method}/#{my_subcategory_method}"
end
end
Note that there might be an issue with routing due to the additional slash, but there's certainly a fix for this, too, if nescessary.
I have a list of cities stored in City table. Let's say I want to generate dynamic routes to be accessible through resource.name, city.name in this example.
I want to be able to visit /amsterdam or /berlin. How?
For info I'm using friendly_id gem so already have slug column if that makes more sense.
Assuming you have friendly_id set up correctly:
match '/cities/:name' => 'cities#show'
or
resources :cities
From the Quick Start for the friendly_id gem:
class City < ActiveRecord::Base
extend FriendlyId
friendly_id :name, use: :slugged
end
Also:
# If you're adding FriendlyId to an existing app and need
# to generate slugs for an existing model, do this from the
# console, runner, or add a Rake task:
City.find_each(&:save)
Here is a RailsCast on it: http://railscasts.com/episodes/314-pretty-urls-with-friendlyid?view=asciicast
At the end of your routes file, add this:
match '*id' => 'cities#show
Then in your CitiesController:
def show
#city = City.find(params[:id])
# ...
end
Don't know if this helps .. but I have put together a gist on what I use in my projects.
https://gist.github.com/1908782
It mostly works for what I do as my routes file is generally quite concise.
The beauty of it is, that if you attempt to visit a path that doesn't exist, it won't hit any routes!
Just a side note, this is broken in the 4.0 release. At the time of writing this, you will need to put the following in your gemfile.
gem 'friendly_id', :git => 'git://github.com/norman/friendly_id.git'
or
gem 'friendly_id', :git => 'https://github.com/norman/friendly_id.git'
Hope this helps.