使用 ActiveAdmin 和 Friendly_id 时的 ActiveRecord::ReadOnlyRecord [英] ActiveRecord::ReadOnlyRecord when using ActiveAdmin and Friendly_id

查看:21
本文介绍了使用 ActiveAdmin 和 Friendly_id 时的 ActiveRecord::ReadOnlyRecord的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始在一个项目中使用 ActiveAdmin,几乎所有东西都运行良好,但在将它与friendly_id gem 结合使用时遇到了问题.我的表单抛出 ActiveRecord::ReadOnlyRecord [我相信],因为其 ID 为只读的friendly_id 属性:

{"utf8"=>"âœ"","_method"=>"put","authenticity_token"="Rc5PmUYZt3BiLvfPQr8iCPPXlbfgjoe/n+NhCwXazNs=","space"=>{"name"=>"The Kosmonaut",地址"=>8 Sichovykh Striltsiv 24","email"=>"info@somedomain.com"},"commit"="更新空间","id"=>"the-kosmonaut"} <--- 罪魁祸首

我猜最后一行是罪魁祸首,因为它是只读属性,它不在我的表单中,而是在 PATH 中

http://localhost:5000/manage/spaces/the-kosmonaut/edit>

如何通过尝试更新 ID 来解决此问题?

ActiveAdmin 中的表单如下所示:

 形式做 |f|f.inputs详细信息"做f.输入:名称f.输入:地址f.输入:电子邮件f.输入:电话f.输入:网站结尾f.inputs内容"做f.输入:描述f.输入:模糊结尾f.按钮结尾

更新:这也不起作用,所以它不是friendly_id?

我尝试使用@watson 的建议,该建议应该有效,但仍然出现相同的错误;-(

{"utf8"=>"âœ"","_method"=>"put","authenticity_token"="Rc5PmUYZt3BiLvfPQr8iCPPXlbfgjoe/n+NhCwXazNs=","space"=>{"name"=>"The Kosmonaut 23"},"commit"="更新空间",id"=>6933"}

http://localhost:5000/manage/spaces/6933/edit

当我在控制台中使用 record.readonly 检查记录时?它返回错误

UPDATE UPDATE:删除scope_以解决问题.

scope_to :current_user, :unless =>proc{ current_user.admin?}

唯一的问题是我需要 scope_to 来防止用户看到他们不拥有的记录.我的猜测是(因为我假设 scope_to 通常与 has_many 一起使用)我的 HABTM 关联会导致一些奇怪的事情?即用户 <-- HABTM --> 空间?

解决方案

如果你只想要前端的友好 ID 而在 Active Admin 中不关心它们,你可以为你的 Active 恢复friendly_id gem 的效果管理员控制器.

我不知道 Friendly_id 是如何覆盖 to_param 方法的,但是如果它以正常方式进行,在所有 Active Admin 控制器中重新覆盖它应该可以解决它,例如:

ActiveAdmin.register Foobar 做before_filter 做Foobar.class_eval 做def to_paramid.to_s结尾结尾结尾结尾

更好的是,您可以在基本 Active Admin 控制器中创建一个 before 过滤器ActiveAdmin::ResourceController,以便它自动继承到您的所有 Active Admin 控制器中.

首先将过滤器添加到 config/initializers/active_admin.rb 设置:

ActiveAdmin.setup do |config|# ...config.before_filter :revert_friendly_id结尾

打开 ActiveAdmin::ResourceController 并添加一个 revert_friendly_id 方法,例如通过将以下内容添加到 config/initializers/active_admin.rb 的末尾:

ActiveAdmin::ResourceController.class_eval 做受保护def revert_friendly_id模型名称 = self.class.name.match(/::(.*)Controller$/)[1].singularize# 如果类不存在,将抛出 NameErrorModule.const_get 模型名称eval(model_name).class_eval 做def to_paramid.to_s结尾结尾救援名称错误结尾结尾

更新:我刚刚更新了最后一个代码示例来处理没有相关模型的控制器(例如 Active Admin Dashboard 控制器)

更新 2:我刚刚尝试将上述 hack 与friendly_id gem 一起使用,它似乎工作得很好:)

更新 3: 清理代码以使用在过滤器之前添加 Active Admin 到基本控制器的标准方法

I started using ActiveAdmin recently in a project and almost everything works great but I'm having a problem when using it in combination with the friendly_id gem. I'm getting ActiveRecord::ReadOnlyRecord thrown for my forms [i believe] because of the friendly_id attribute whose ID is readonly:

{"utf8"=>"âœ"",
"_method"=>"put",
"authenticity_token"=>"Rc5PmUYZt3BiLvfPQr8iCPPXlbfgjoe/n+NhCwXazNs=",
"space"=>{"name"=>"The Kosmonaut",
"address"=>"8 Sichovykh Striltsiv 24",
"email"=>"info@somedomain.com"},
"commit"=>"Update Space",
"id"=>"the-kosmonaut"}  <--- culprit

I'm guessing the last line is the culprit as it's a readonly attribute, it's not in my form but rather in the PATH

http://localhost:5000/manage/spaces/the-kosmonaut/edit

How can I fix this from trying to update the ID?

Form from in ActiveAdmin looks like this:

  form do |f|
    f.inputs "Details" do
      f.input :name
      f.input :address
      f.input :email
      f.input :phone
      f.input :website
    end
    f.inputs "Content" do
      f.input :description
      f.input :blurb
    end
    f.buttons
  end

UPDATE: This doesn't work either so it's not the friendly_id?

I tried using @watson's suggestion which should have worked but still got the same error ;-(

{"utf8"=>"âœ"",
 "_method"=>"put",
 "authenticity_token"=>"Rc5PmUYZt3BiLvfPQr8iCPPXlbfgjoe/n+NhCwXazNs=",
 "space"=>{"name"=>"The Kosmonaut 23"},
 "commit"=>"Update Space",
 "id"=>"6933"}

http://localhost:5000/manage/spaces/6933/edit

When I check the record in the console with record.readonly? it returns false

UPDATE UPDATE: removing the scope_to fixes the problem.

scope_to :current_user, :unless => proc{ current_user.admin? }

Only problem is I need the scope_to to prevent users from seeing records they do not own. My guess is (as I'm assuming scope_to normally works with has_many) that my HABTM association causes some weirdness? Ie Users <-- HABTM --> Spaces?

解决方案

If you only want friendly ID's in the front end and don't care about them inside Active Admin, you can revert the effects of the friendly_id gem for your Active Admin controllers.

I don't know exactly how friendly_id overrides the to_param method, but if it's doing it the normal way, re-overriding it inside all of your Active Admin controllers should fix it, e.g.:

ActiveAdmin.register Foobar do
  before_filter do
    Foobar.class_eval do
      def to_param
        id.to_s
      end
    end
  end
end

Even better you could create a before filter in the base Active Admin controller ActiveAdmin::ResourceController so that it is automatically inherited into all your Active Admin controllers.

First add the filter to the config/initializers/active_admin.rb setup:

ActiveAdmin.setup do |config|
  # ...
  config.before_filter :revert_friendly_id
end

The open up ActiveAdmin::ResourceController and add a revert_friendly_id method, E.g. by adding the following to the end of config/initializers/active_admin.rb:

ActiveAdmin::ResourceController.class_eval do
  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

Update: I just updated the last code example to handle controllers with no related model (e.g. the Active Admin Dashboard controller)

Update 2: I just tried using the above hack together with the friendly_id gem and it seems to work just fine :)

Update 3: Cleaned up the code to use the standard way of adding Active Admin before filters to the base controller

这篇关于使用 ActiveAdmin 和 Friendly_id 时的 ActiveRecord::ReadOnlyRecord的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆