hol*_*den 16 ruby-on-rails readonly friendly-id ruby-on-rails-3 activeadmin
我最近在一个项目中开始使用ActiveAdmin,几乎所有东西都运行良好但是当我将它与friendly_id gem结合使用时遇到了问题.我正在为我的表单[我相信]抛出ActiveRecord :: ReadOnlyRecord,因为friendly_id属性的ID是只读的:
{"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
Run Code Online (Sandbox Code Playgroud)
我猜最后一行是罪魁祸首,因为它是一个只读属性,它不是我的形式,而是在PATH中
HTTP://本地主机:5000 /管理/空间/的-kosmonaut /编辑
如何通过尝试更新ID来解决此问题?
ActiveAdmin中的表单如下所示:
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
Run Code Online (Sandbox Code Playgroud)
更新:这不起作用,所以它不是friendly_id?
我尝试使用@ watson的建议应该有效,但仍然有同样的错误;-(
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"Rc5PmUYZt3BiLvfPQr8iCPPXlbfgjoe/n+NhCwXazNs=",
"space"=>{"name"=>"The Kosmonaut 23"},
"commit"=>"Update Space",
"id"=>"6933"}
Run Code Online (Sandbox Code Playgroud)
HTTP://本地主机:5000 /管理/空间/ 6933 /编辑
当我用record.readonly检查控制台中的记录时?它返回false
更新更新:删除scope_to可以解决问题.
scope_to :current_user, :unless => proc{ current_user.admin? }
Run Code Online (Sandbox Code Playgroud)
唯一的问题是我需要使用scope_to来防止用户看到他们不拥有的记录.我的猜测是(因为我假设scope_to通常与has_many一起使用)我的HABTM关联会导致一些奇怪吗?用户< - HABTM - >空格?
Tho*_*son 28
如果您只想在前端使用友好ID而不关心Active Admin中的内容,则可以为您的Active Admin控制器恢复friendly_id gem的效果.
我不确切知道friendly_id如何覆盖该to_param方法,但如果它以正常方式执行,则在所有Active Admin控制器内重新覆盖它应该修复它,例如:
ActiveAdmin.register Foobar do
before_filter do
Foobar.class_eval do
def to_param
id.to_s
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
更好的是,您可以在基本Active Admin控制器中创建一个前置过滤器,ActiveAdmin::ResourceController以便它自动继承到所有Active Admin控制器中.
首先将过滤器添加到config/initializers/active_admin.rb设置中:
ActiveAdmin.setup do |config|
# ...
config.before_filter :revert_friendly_id
end
Run Code Online (Sandbox Code Playgroud)
打开ActiveAdmin::ResourceController并添加一个revert_friendly_id方法,例如通过在结尾添加以下内容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
Run Code Online (Sandbox Code Playgroud)
更新:我刚刚更新了最后一个代码示例来处理没有相关模型的控制器(例如Active Admin Dashboard控制器)
更新2:我刚尝试使用上面的hack和friendly_id gem,它似乎工作得很好:)
更新3:清除代码以使用在过滤器之前将Active Admin添加到基本控制器的标准方法
Den*_*nny 16
您可以根据http://activeadmin.info/docs/2-resource-customization.html#customizing_resource_retrieval自定义资源检索.请注意,您要使用该find_resource方法而不是resource,或者您将无法创建新记录.
(有关详细信息,请查看https://github.com/gregbell/active_admin/blob/master/lib/active_admin/resource_controller/data_access.rb)
在您的ActiveAdmin资源类中写入:
controller do
def find_resource
scoped_collection.where(slug: params[:id]).first!
end
end
Run Code Online (Sandbox Code Playgroud)
您还可以通过在active_admin.rb初始化程序中修改ResourceController来覆盖所有资源的行为.
ActiveAdmin::ResourceController.class_eval do
def find_resource
if scoped_collection.is_a? FriendlyId
scoped_collection.where(slug: params[:id]).first!
else
scoped_collection.where(id: params[:id]).first!
end
end
end
Run Code Online (Sandbox Code Playgroud)
希望有所帮助!
附注:通过管理界面创建新记录时,请确保不在表单中包含slug字段,否则FriendlyId将不会生成slug.(我相信只有5+版本)
| 归档时间: |
|
| 查看次数: |
3794 次 |
| 最近记录: |