ruby-on-railsactiveadminfriendly-id

Friendly_id and Active Admin conflict - possibly because of revert_freindly_id


first time asking a question on stack overflow :)

I'm having a conflict between friendly_id and active admin (it's an assumption), as discussed in many threads here. I've looked at all those threads, but I'm not entirely sure they solve my problem. Sorry for the really long post!

I'm trying to create friendly links to products on my website. I've added the friendly_id gem and everything works fine in my dev and staging environments, but friendly links fail on production. Here is all my code:

Model:

class Product < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: :slugged
  ...
end

Controller:

class ProductsController < ApplicationController
  before_filter :get_product, only: [:show]
  ...

  private

  def get_product
    @product = Product.friendly.find(params[:id])
  end
end

All my product records have a completed slug field at this point. I don't want to use slugs in my admin interface, so when I came across a solution here, I went ahead and modified it a bit to get active admin to work together with friendly_id.

config/initializers/active_admin.rb:

ActiveAdmin.setup do |config|
  ...

  config.before_filter :revert_friendly_id
end

I've defined revert_friendly_id in the application controller:

class ApplicationController < ActionController::Base
  ...
  protected

  def revert_friendly_id
    model_name = self.class.name.match(/::(.*)Controller$/)[1].singularize

    # Will throw a NameError if the class does not exist
    Module.const_get model_name

    eval(model_name).class_eval do
      def to_param
        id.to_s
      end
    end
    rescue NameError
  end
end

I've noticed that when I first deploy to production via capistrano, the friendly links work as expected. So my product links are accessible with: http://website.com/products/my-product-slug. But the minute I access the admin interface on production, the links immediately switch back to product ids instead: http://website.com/products/12345. I'm not entirely sure how to resolve this problem, though I understand why it might be happening, can someone help me please?


Solution

  • Here is how I solved the problem. Based on armstrjare's fix at this link.

    I removed the revert_friendly_id function from my application controller and the before_filter from my config. Then just added the following to app/admin/product.rb:

    ActiveAdmin.register Product do
    
      around_filter do |controller, action|
        Product.class_eval do
          alias :__active_admin_to_param :to_param
          def to_param() id.to_s end
        end
    
        begin
          action.call
        ensure
          Product.class_eval do
            alias :to_param :__active_admin_to_param
          end
        end
      end
    ...
    end
    

    And everything worked as expected. Hope this helps someone else!