-
-
Notifications
You must be signed in to change notification settings - Fork 591
Tips and Tricks
Feel free to add any helpful hints for other users here.
Submitted by maxcal
Case:
We want our post class to have slug and title attributes that are editable by the user. The user should be able to edit the title and slug independently. The slug should default to a slugged version of the title.
example output:
post = Post.create(title: "How Long is a Long Long Time", slug: 'how-long')
post.slug
# 'how-long'
post = Post.create(title: "How Long is a Long Long Time")
post.slug
# 'how-long-is-a-long-long-time'
class Post < ActiveRecord::Base
extend FriendlyId
friendly_id :title, :use => [:slugged]
validates_presence_of :title
def should_generate_new_friendly_id?
slug.blank? && title_changed?
end
end
Submitted by benpolinsky
Case:
We want our Post to have an editable slug that doesn't default to another field. The record's id will be used if no slug is set.
example output:
post = Post.create(title: "How Long is a Long Long Time")
post.slug
# nil
post.update_attributes(title: "Some other title", temporary_slug: "My favorite post)
post.slug
# 'my-favorite-post'
class Post < ActiveRecord::Base
attr_accessor :temporary_slug
extend FriendlyId
friendly_id :temporary_slug, :use => [:slugged]
def should_generate_new_friendly_id?
temporary_slug_changed?
end
# track changes in non persisted attribute
def temporary_slug=(value)
attribute_will_change!('temporary_slug') if temporary_slug != value
@temporary_slug = value
end
def temporary_slug_changed?
changed.include?('temporary_slug')
end
end
Submitted by anonoz
If your existing model has a lot of callbacks, validations etc, you can skip all of them by creating an empty model class of its own inside migration file. For example:
class AddFriendlyIdToCompanies < ActiveRecord::Migration[5.0]
disable_ddl_transaction!
# Bare minimum class to skip all callbacks
class FriendlyIdCompany < ActiveRecord::Base
self.table_name = 'companies'
extend FriendlyId
friendly_id :slug_candidate, use: [:slugged, :finders]
def slug_candidate
"#{name}"[0, 20] + " #{SecureRandom.hex[0, 6]}"
end
end
def up
unless column_exists?(:companies, :slug)
add_column :companies, :slug, :text
add_index :companies, :slug, unique: true, algorithm: :concurrently
end
print "Updating friendly_id slug for companies"
FriendlyIdCompany.each do |row|
row.save; print('.')
end
puts ' '
end
def down
remove_index :companies, :slug
remove_column :companies, :slug
end
end
Just remember to not inclyde the history
plug in, it doesn't work well with this because the sluggable_type
will not be pointing to the original model class. You can use history
in the normal model class with callbacks later on.