RoR - Get the strong controller parameters inside the Application Controller

2

I'm developing a logging process on my system (Rails 5), more specifically within application controller . This process is being created there so that I can add a before_save to the controllers that I want to record logs. Since there are several controllers , I'm centralizing the method instead of repeating it multiple times in each file. The logging process works like this: when the user clicks the "Save" button, in% editing%, the system will search the BD for the current record of the object that the user is editing and compare these records with the form fields %. If the records are different, it means that the user has changed some data. The old data is saved as log and the new one is written to the DB. Home Here's what I have so far:

def gerar_log
    @controlr = instance_variable_get("@#{controller_name.singularize}") #objeto que está sendo editado
    nome_cols = @controlr.attribute_names #pega o nome das colunas da tabela do objeto
    ctrl_obj = @controlr.attributes #pega os dados do objeto do BD
    dados_editados = self.strong_params #pega os strong params do controller, que contém o que foi alterado nos campos do form. Estou preso aqui =/
    ...
    ##compara os dados_editados com os dados atuais do objeto e verifica se algo mudou
end

The problem I'm having in this process is when I get the form of strong parameters . Since it's a controller method, you can not call it directly. I tried to create a private method, called public , which returns the strong_params of the private method, but it generates the following error: params . If anyone knows of a solution to this, or if there is a better and equally dynamic way of doing this other than param is missing or the value is empty: , I'm grateful if you can let me know.

EDIT - I do not want to use gems for this process, because it's super simple. The only hurdle at the moment is to dynamically get the application controller of each strong parameters . If I can not do within controller , I can do this by setting a method within each application_controller as follows:

../ controllers / people_controller.erb

def log
    @pessoas = Pessoa.find(params[:id]) #busca a pessoa que está sendo editada
    colunas = @pessoas.attribute_names #pega o nome das colunas da tabela pessoa
    parametros = pessoa_params.merge(:id => params[:id]) #pega os dados que estão sendo editados no form e adiciona o ID
    pess = @pessoas.attributes #pega os dados da pessoa do BD
    alteracoes = {}

    colunas.each_index do |i|
    ##compara os dados_editados com os dados atuais do objeto e verifica se algo mudou
    #Se mudou, atualiza a pessoa com os novos dados e salva os dados antigos na tabela de log
      if parametros[colunas[i]].to_s != pess[colunas[i]].to_s 
        alteracoes[colunas[i]] = pess[colunas[i]].to_s unless parametros[colunas[i]].nil?
      end

    end

    @logs = Log.new
    @logs.gera_log(current_user.id, controller_name, params[:id], alteracoes) unless alteracoes.nil? || alteracoes.empty?

  end

To generate controller before the user refreshes the information:

before_save :log, only: [:update]

The good thing about it is that it does exactly what I need. The bad side is that I need to set this method on every log I want to generate controller , and this goes against log policy. So I want to know if you have a way to centralize this method and make it dynamic for each controller, without using gems!

    
asked by anonymous 30.10.2017 / 18:30

1 answer

1

The best way I know to do this is by using the Paper Trail gem, it is extremely dynamic and effective for this type of solution. I use it extensively in my projects for auditing , versioning and recovery of data.

In case of this gem the data will be recorded in database and not in logs, but do not worry, it generates its own migrations. Then just add before_action to your ApplicationController :

class ApplicationController
  before_action :set_paper_trail_whodunnit
end

And inform every% of% who will be audited by model :

class Widget < ActiveRecord::Base
  has_paper_trail
end

It's extremely customizable and powerful, so I recommend reading your README .

I think it falls like a glove for your need.

    
31.10.2017 / 12:21