How to obfuscate user id with random number using friendly_id - ruby-on-rails

When my new website launches there will be very few users. Currently a user's profile page is /users/:id so in the early stages it will be /users/6, etc. I don't want others to know how many users the website has. I think that an long id (such as a uuid) with numbers and letters looks ugly so I would prefer it just be numbers.
How can I use friendly_id gem to create a random number slug that will also be unique? This is also my first website so any "best practices" tips regarding user id obfuscation would be helpful. Thanks.

This is an example from existing project:
class User < ActiveRecord::Base
extend FriendlyId
friendly_id :email, use: [:slugged, :finders]
def normalize_friendly_id(email)
Digest::MD5.hexdigest(email)
end
def should_generate_new_friendly_id?
slug.blank?
end
end
You can change the MD5 to a random number using something like this:
SecureRandom.random_number(1_000_000_000)

Related

How to avoid FriendlyId creating a different slug if current already exists

I'm using FriendlyId gem on Ruby on Rails 5.
Is there any way to stop FriendlyId to create a different slug if the current one has already been taken? I'd like the user to have full control over the slug.
Add this method to your Model.
def should_generate_new_friendly_id?
new_record?
end
or modify the content of the method to match your needs.

rails friendly_id bad request

I'm new to rails and currently involved in an internship and I was assigned to use the friendly_id gem for my tournament class, this is part of the code in it:
class Tournament < ApplicationRecord
extend FriendlyId
friendly_id :url_id
...
end
I don't use a slug since I have a url_id attribute that stores my desired url and when I try with the old .../tournaments/1 everything's all good but with .../tournaments/example I get "example is not a valid value for id" with code 103, status 400. Any ideas what the problem might be?
You have to update your controller for Tournaments so that it uses friendly.find method instead of the find.
# Change this:
Tournament.find(params[:id])
# to
Tournament.friendly.find(params[:id])

Change the unique generated title names of friendly-id using attribute of another table

I have a Company Model, and i am using friendly_id like this
friendly_id :name, use: :slugged
But since there can be many Company with the same name (different branches). I am trying to handle that case by using city attribute from the address of the Company.
But the Company address is stored in a different table Address.
so company.address.city gives me the city of the company.
friendly_id :slug_candidates, use: :slugged
# Try building a slug based on the following fields in
# increasing order of specificity.
def slug_candidates
[
:name,
[:name, :city]
]
end
I'm aware i can do something like above. But since city is not an attribute of company how can i achieve this?
Update:
Possible solution for this is to create a helper method city which returns the company's city.
But the problem never was that.
The version of friendly_id i am using is 4.0.10.1
and the feature which enables the usage of slug_candidates are available in versions 5 and above.
I tried updating the gem. But it wont get updated as version 5 has dependency on activerecord 4.0 and rails has dependency on activerecord 3.2.13
It's kind of a deadlock. Don't know what to do
class Company < ActiveRecord::Base
.............................
def city
self.address.city
end
end

scaling issues using friendly_id

Okay so I'm working on making a friendly_id that allows me to scale it effectively. This is what I got so far. What it does is essentially add +1 on a count if you have a matching name. So if you are the 2nd person to register as John doe your url would be /john-doe-1.
extend FriendlyId
friendly_id :name_and_maybe_count, use: [:slugged, :history]
def name_and_maybe_count
number = User.where(name: name).count
return name if number == 0
return "#{name}-#{number}"
end
However this piece of code is still bringing me some issues.
If I have created a user called John Doe. Then register another user called John Doe the slug will be /john-doe-UUID. If I register a third user then it will receive the slug john-doe-1.
If I have two users. One that registered with the name first. Say Juan Pablo. Then he changes his name to 'Rodrigo', and then change it back to 'Juan Pablo'. His new slug for his original name will be 'juan-pablo-1-UUID'.
I know this is minor nitpick for most of you but it's something that I need to fix!
You want to overwrite to_param, include the id as the first bit of the friendly id
I extend active record like this in one of my apps,
module ActiveRecord
class Base
def self.uses_slug(attrib = :name)
define_method(:to_param) do
"#{self.id}-#{self.send(attrib).parameterize}"
end
end
end
so I can do
uses_slug :name
in any model
but this alone in any model should work:
def to_param
"#{self.id}-#{self.my_attrib.parameterize}"
end
The benefit of this is that in the controller you when you do
Model.find(params[:id])
you don't have to change anything because when rails tries to convert a string like "11-my-cool-friendly-id" it will just take the first numeric bits and leave the rest.

how to display path with FriendlyId, rails

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.

Resources