kon*_*ung 5 json ruby-on-rails kendo-ui strong-parameters ruby-on-rails-4
我有几个模型,每个模型有40个属性.它们被标准化,只是我们正在处理的模型必须具有多个属性.除此之外,它是一个非常标准的rails 4.2应用程序(从rails 3.2升级).该应用程序既可用于提供带有ajax调用的动态页面,也可用于json,因此可供各种json客户端使用.
所以请致电:http://example.com/products/1.json - 返回json和http://example.com/products/1返回haml-parsed视图.
我正在使用的JavaScript库(KendoUI)返回更新的整个记录,而不仅仅是更新的字段.目前没有办法避免,除非我想根据他们的支持论坛重写KendoUi Grid.
因此,用户可以搜索所有产品,并向她显示产品的所有属性,然后根据她的访问级别,她可以更新某些字段(几个定价点和描述),但是ajax请求包含所有属性.因此,我得到了ActiveModel :: ForbiddenAttributesError
我怎样才能正确(可以这么说的轨道)过滤掉更新后的参数?现在我正在对@ product.attributes && params [:product]进行哈希比较,以确定是否传递了更新/新属性..diff自Rails 4.0.2起已被弃用
我的管理员可以更改这些大型模型上的几乎所有属性(时间戳,ID和其他一些除外).最好的方法是做什么而不是做params [:product] .require(:base_cost).permit(:vendor_cost,:client_cost)30个奇数属性?如果应用程序处于开发状态并且属性发生变化,则很快就会成为维护这些列表的问题.我想我可以使用某种CONSTANT - ALLOWED_ATTRIBUTES或ADMIN_ATTRIBUTES和USER_ATTRIBUTES,并将其传递给permit.但有点感觉不Railsy?
第1部分
即使该功能已被弃用,您仍然可以使用该功能。您尝试做的一些事情可能在这里有用。
class Hash
def diff h2
self.dup.delete_if { |k, v| h2[k] == v }.merge(h2.dup.delete_if { |k, v| self.has_key?(k) })
end
def only *args
h = {}
args.each do |a|
h[a] = self[a]
end
h
end
def except *args
h = {}
(self.keys - args).each do |a|
h[a] = self[a]
end
h
end
end
Run Code Online (Sandbox Code Playgroud)
测试
2.0.0-p247 :001 > h1 = {a: 1, b: 2, c: 3} #=> {:a=>1, :b=>2, :c=>3}
2.0.0-p247 :002 > h2 = {a: 3, b: 2, c: 1} #=> {:a=>3, :b=>2, :c=>1}
2.0.0-p247 :003 > h1.except(:a) #=> {:b=>2, :c=>3}
2.0.0-p247 :004 > h1.except(:c) #=> {:a=>1, :b=>2}
2.0.0-p247 :005 > h1.except(:c, :a) #=> {:b=>2}
2.0.0-p247 :006 > h1.only(:c, :a) #=> {:c=>3, :a=>1}
Run Code Online (Sandbox Code Playgroud)
要记住的一件事是参数可能不会真正以哈希形式出现,因此您可能必须调用 .to_hash
第2部分
class FooBar < ActiveRecord::Base
#this controls access restriction, assuming you keep this setup:
#delete this part and all fields are update-able (leave it undefined)
#no fields can be updated if UPDATABLE_FIELDS[type].nil? or UPDATABLE_FIELDS[type][0].nil?
UPDATABLE_FIELDS = {
admin: [:except, :id, :timestamp],
user: [:only, :name]
}
end
class ActiveRecord::Base
def fields_for_user_type type
return true unless defined?(UPDATABLE_FIELDS)
return nil if !UPDATABLE_FIELDS[type] || !UPDATABLE_FIELDS[type].first
return UPDATABLE_FIELDS[type].first, UPDATABLE_FIELDS[type][1..-1]
end
end
class ApplicationController < ActionController::Base
def filter_params data, cls
method, restriction = cls.fields_for_user_type(current_user.type)
return data if method === true
return {} if method.nil?
return data.except(restriction) if method == :except
return data.only(restriction) if method == :only
end
end
class FunController < ApplicationController
def update
record = FooBar.find(params[:id])
record.update(filter_params(params[:data], FooBar))
end
end
Run Code Online (Sandbox Code Playgroud)
您可以很容易地为此添加默认值以及其他一些漂亮的功能,但至少作为一个开始,这应该可以为您做到这一点。
请记住,并非所有这些都经过彻底测试,可能存在错误!
| 归档时间: |
|
| 查看次数: |
467 次 |
| 最近记录: |