gpt4 book ai didi

ruby-on-rails - Rails 4.2 强参数和解析 json put/update 上更改的属性

转载 作者:行者123 更新时间:2023-12-04 21:40:56 28 4
gpt4 key购买 nike

背景
我有几个模型,每个模型大约有 40 个属性。它们是标准化的,只是我们正在处理的模型必须具有多个属性。除此之外,它是一个非常标准的 rails 4.2 应用程序(从 rails 3.2 升级)。该应用程序既用于提供带有 ajax 调用的动态页面,也用于 json,因此它可以被各种 json 客户端使用。
所以调用:http://example.com/products/1.json - 返回 json 和 http://example.com/products/1返回 haml 解析的 View 。
问题
我正在使用的 JavaScript 库(KendoUI)在更新时返回整个记录,而不仅仅是更新的字段。目前没有办法避免,除非我想根据他们的支持论坛重写 KendoUi Grid。
因此用户可以搜索所有产品,我将产品的所有属性显示给她,然后根据她的访问级别,她可以更新某些字段(几个定价点和描述),但是 ajax 请求包含所有属性。因此,我得到 ActiveModel::ForbiddenAttributesError

第1部分
我怎样才能正确地(可以说是 rails 方式)过滤掉更新的参数?现在我正在对 @product.attributes && params[:product] 进行哈希比较,以确定是否有更新/新属性传递。 .diff 从 Rails 4.0.2 开始被弃用
第2部分
我的管理员可以更改这些大模型的几乎所有属性(时间戳、ID 和其他一些属性除外)。什么是最好的方法而不是为 30 个奇怪的属性做 params[:product].require(:base_cost).permit(:vendor_cost, :client_cost) ?如果应用程序处于开发阶段并且属性发生变化,维护这些列表很快就会成为一个问题。我想我可以使用某种常量 - ALLOWED_ATTRIBUTES 或 ADMIN_ATTRIBUTES 和 USER_ATTRIBUTES,并将其传递给允许。但有点感觉不像 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

测试
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}

要记住的一件事是 params 可能不会真正以哈希形式出现,因此您可能必须调用 .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

您可以很容易地为此添加默认值和其他一些漂亮的功能,但至少作为开始,这应该为您做。

请记住,并非所有这些都经过彻底测试,可能存在错误!

关于ruby-on-rails - Rails 4.2 强参数和解析 json put/update 上更改的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26392580/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com