Rails 4.2 strong params and parsing changed attributes on a json put / update Rails 4.2 strong params and parsing changed attributes on a json put / update json json

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!