Rails 4.2 strong params and parsing changed attributes on a json put / update
Part 1
Even if the function is deprecated you can still use this functionality. With what your trying to do a few might be useful here.
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 endend
Tests
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}
One thing to keep in mind is the params may not truly come in as a hash, so you may have to call .to_hash
Part 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] }endclass 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] endendclass 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 endendclass FunController < ApplicationController def update record = FooBar.find(params[:id]) record.update(filter_params(params[:data], FooBar)) endend
You could add defaults to this pretty easily and some other nifty pieces of functionality but at least as a start this should do it for you.
Please keep in mind not all this has been thoroughly tested, there could be bugs!