Search code examples
rubyruby-on-rails-4friendly-id

Friendly with existing Rails 4 app: No change


I have an existing app with devise running. User and log in and out etc. Thought I would like to get localhost:3000/users/15 changed to localhost:3000/users/ruby-boy so I have installed https://github.com/norman/friendly_id

I have ran rails generate friendly_id but when I ran rails generate scaffold user name:string slug:string:uniq, it say I already got a user.rb file so ok I've added: rails g migration AddSlugToUser slug:string:uniq and rails g migration AddNameToUser name:string. So I've added those two columns to my users table.

In my controllers I've replaced:

User.find(params[:id])

with:

User.friendly.find(params[:id])

Then ran this in console (rails c)

User.find_each(&:save)

But User.find_each(&:save) gave:

 (0.1ms)  commit transaction
 (0.0ms)  begin transaction
 => nil

I think I've followed the docs "eye for eye". Have I missed anything as the links wont change.

PS: I have edited the user.rb per website on github.

My user.rb:

class User < ActiveRecord::Base
       extend FriendlyId
      friendly_id :name, use: :slugged
      # Include default devise modules. Others available are:
      # :confirmable, :lockable, :timeoutable and :omniauthable
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :trackable, :validatable
      belongs_to :plan
      has_one :profile

      attr_accessor :stripe_card_token

      def save_with_payment
        if valid?
            customer = Stripe::Customer.create(description: email, plan: plan_id, card: stripe_card_token)
            self.stripe_customer_token = customer.id
            save!
        end
      end
    end

Schema for users table:

create_table "users", force: :cascade do |t|
      t.string   "email",                  default: "", null: false
      t.string   "encrypted_password",     default: "", null: false
      t.string   "reset_password_token"
      t.datetime "reset_password_sent_at"
      t.datetime "remember_created_at"
      t.integer  "sign_in_count",          default: 0,  null: false
      t.datetime "current_sign_in_at"
      t.datetime "last_sign_in_at"
      t.string   "current_sign_in_ip"
      t.string   "last_sign_in_ip"
      t.datetime "created_at"
      t.datetime "updated_at"
      t.integer  "plan_id"
      t.string   "stripe_customer_token"
      t.string   "slug"
      t.string   "name"
    end

Solution

  • Add :name to your sign up form and then validate for uniqueness in your User model

    Class User
      validates :name, uniqueness: true
    

    This way same name can't be created more than once and you'll avoid avoid weird slugs.