ruby-on-rails Friendly_id与活动管理员冲突-可能是由于revert_freindly_id

0ve6wy6x  于 2022-11-19  发布在  Ruby
关注(0)|答案(4)|浏览(97)

第一次提出关于堆栈溢出的问题:)
我遇到了friendly_id和active admin之间的冲突(这是一个假设),正如在这里的许多线程中所讨论的。我已经查看了所有这些线程,但我不完全确定它们是否解决了我的问题。抱歉,我的帖子太长了!
我正在尝试在我的网站上创建指向产品的友好链接。我添加了friendly_id gem,在我的开发和过渡环境中一切都很好,但是友好链接在生产环境中失败了。以下是我的全部代码:

型号:

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

控制器:

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

  private

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

我不想在我的管理界面中使用slugs,所以当我遇到一个解决方案here时,我继续修改了一下,让active admin与friendly_id一起工作。

配置/初始化程序/active_admin.rb:

ActiveAdmin.setup do |config|
  ...

  config.before_filter :revert_friendly_id
end

我已经在应用程序控制器中定义了revert_friendly_id:

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

我注意到,当我第一次通过capistrano部署到生产环境时,友好的链接可以正常工作。因此,我的产品链接可以通过以下方式访问:http://website.com/products/my-product-slug。但是,当我访问生产上的管理界面时,链接立即切换回产品ID:http://website.com/products/12345。我不完全确定如何解决这个问题,虽然我知道为什么会发生这个问题,有人能帮助我吗?

k4ymrczo

k4ymrczo1#

下面是我如何解决这个问题的。基于armstrjare在this link的修复。
我从我的应用程序控制器中删除了revert_friendly_id函数,并从我的配置中删除了before_filter。然后,我只在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

而且一切都如预期的那样工作。希望这对其他人有帮助!

wr98u20j

wr98u20j2#

我找到了一个非常简单的解决办法:只需覆盖模型中的to_param,并检查是否从active_admin调用了它。
应用程序/模型/产品.rb:

class Product < ActiveRecord::Base
  def to_param
    if caller.to_s.include?"active_admin"
      id && id.to_s
    else
      slug
    end
  end
end
wr98u20j

wr98u20j3#

当你设置to_param方法时,它将被设置在整个应用程序上。所以你必须检查请求的控制器是否在Admin命名空间中。基于此,你必须切换回to_param方法的返回。

xuo3flqw

xuo3flqw4#

您可以在controller中重新定义find_resource方法:

controller do
      def find_resource
        scoped_collection.friendly.find(params[:id])
      end
   end

对于active_adminbelongs_to关联,您可以使用finder:选项(来自https://github.com/activeadmin/继承的资源/blob/master/lib/继承的资源/归属地_到_助手. rb#L17)
例如:belongs_to :content, finder: :find_by_slug!

相关问题