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!