更新后删除旧的friendly_id gem slu

时间:2018-02-05 23:38:49

标签: ruby-on-rails ruby ruby-on-rails-5 slug friendly-id

Scenerio:

1-用户使用用户名 elon_musk

注册

2-个人资料网址是mywebsite.com/users/elon_musk

3- Elon将其用户名编辑为 elonmusk

4-现在他的个人资料网址是mywebsite.com/users/elonmusk

到目前为止一切都很好,但我注意到mywebsite.com/users/elon_musk仍然可用!现在Elon有2个档案网址!

如何更新 elonmusk 时删除 elon_musk slug

谢谢!

用户表:

  create_table "designers", force: :cascade do |t|
    t.string "fullname"
    t.string "website"
    t.string "bio"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string "avatar"
    t.string "slug"
    t.string "twitter"
    t.string "email", default: "", null: false
    t.string "username"
    t.string "location"
    t.boolean "featured", default: false
    t.string "twitter_username"
    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.inet "current_sign_in_ip"
    t.inet "last_sign_in_ip"
    t.boolean "is_admin", default: false
    t.string "provider"
    t.string "uid"
    t.index ["email"], name: "index_designers_on_email"
    t.index ["reset_password_token"], name: "index_designers_on_reset_password_token", unique: true
  end

omniauth_callbacks_controller

class OmniauthCallbacksController < Devise::OmniauthCallbacksController
    def all
        designer = Designer.from_omniauth(request.env['omniauth.auth'])

        if designer.persisted?
            sign_in_and_redirect designer, notice: "Signed in!"
        else
            session["devise.designer_attributes"] = designer.attributes
            redirect_to new_designer_registration_url
        end
    end
    alias_method :twitter, :all
end

registration_controller.rb

class RegistrationsController < Devise::RegistrationsController

  def sign_up_params
    params.require(:designer).permit(:username, :fullname, :email, :password, :password_confirmation)
  end

  def account_update_params
    params.require(:designer).permit(:username, :fullname, :email, :location, :website, :twitter, :bio, :featured, :is_admin, :password, :password_confirmation, :current_password)
  end


  protected

  def after_sign_up_path_for(resource)
    edit_designer_path(current_designer) if current_designer
  end

end

designer.rb

class Designer < ApplicationRecord
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable, omniauth_providers: [:twitter]

  has_many :posts

  mount_uploader :avatar, AvatarUploader

  extend FriendlyId
  friendly_id :username, use: [:slugged, :history]

  validates_presence_of     :email # optional
  validates_uniqueness_of   :email # required    
  validates_presence_of     :username # required
  validates_uniqueness_of   :username # required    
  validates_presence_of     :password, if: :password_required? # recommended
  validates_confirmation_of :password, if: :password_required? # recommended
  validates_length_of       :password, within: password_length, allow_blank: true # recommended

  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |designer|
      designer.provider = auth.provider
      designer.uid = auth.uid

      designer.slug = auth.info.nickname
      designer.username = auth.info.nickname
      designer.twitter_username = auth.info.nickname

      designer.email = auth.info.email 
      designer.password = Devise.friendly_token[0, 20]
      designer.fullname = auth.info.name 
      designer.remote_avatar_url = auth.info.image.sub("_normal", "") unless designer.avatar.present?
    end
  end

  def self.new_with_session(params, session)
    if session["devise.designer_attributes"]
      new(session["devise.designer_attributes"]) do |designer|
        designer.attributes = params
        designer.valid?
      end
    else
      super
    end
  end

  def password_required?
    super && provider.blank?
  end

  def update_with_password(params, *options)
    if encrypted_password.blank?
      update_attributes(params, *options)
    else
      super
    end
  end

  def should_generate_new_friendly_id?
    slug.blank? || username_changed?
  end

end

2 个答案:

答案 0 :(得分:4)

中删除:历史记录
friendly_id :username, use: [:slugged, :history]

http://www.rubydoc.info/github/norman/friendly_id/FriendlyId/History

答案 1 :(得分:0)

我想首先建议您提供更多信息,例如控制器中的代码。

我认为您没有正确设置宝石 - 请务必遵循documentation

friendly_id gem在用户上使用名为slug的属性,因此用户应该只有一个 - 它直接在用户表上(不是连接或关联表)。

您还需要确保User params在更新时接受参数slug。然后,在更新中,它应该自动更新。

 class RegistrationsController < Devise::RegistrationsController

  def sign_up_params
    params.require(:designer).permit(:username, :fullname, :email, :password, :password_confirmation, :slug)
  end

  def account_update_params
    params.require(:designer).permit(:username, :fullname, :email, :location, :website, :twitter, :bio, :featured, :is_admin, :password, :password_confirmation, :current_password, :slug)
  end
 end