Returning last value

Hi.

I have the following controller of the update action:

[code]
def update
    @projeto = Projeto.find(params[:id])

    if (@projeto.update_attributes(params[:projeto]))

    ## Mesmo raciocínio utilizado no create.
    @permissaoA = Permissao.find(:first, :conditions => ["usuario_id =
?", @projeto.responsavel.to_i])
    @permissaoAvancado1 = Permissao.find(:first, :conditions =>
["projeto_id = ? and usuario_id = ?", 0, @projeto.responsavel.to_i])
    if @permissaoAvancado1.nil?
    ## Caso tenham excluido os usuários responsáveis, as permissões
seriam nulas. Dai ele verifica se vai alterar ou criar uma permissão
    if @permissaoA.nil?
    @permissaoAv = Permissao.new(params[:permissao])
    @permissaoAv.perfil = "Avançado"
    @permissaoAv.usuario = Usuario.find(:first, :conditions => ["id =
?", @projeto.responsavel.to_i])
    @permissaoAv.save(params[:permissao])
    end
    end

    ## O mesmo que avançado
    @permissaoI = Permissao.find(:first, :conditions => ["projeto_id = ?
and perfil = ? and usuario_id = ?", @projeto.id, "Intermediário",
@projeto.responsavel_td.to_i])
    @permissoesB = Permissao.all(:conditions => ["projeto_id = ? and
usuario_id = ? and perfil = ?", @projeto.id,
@projeto.responsavel_td.to_i, "Básico"])
    @permissaoAvancado2 = Permissao.find(:first, :conditions =>
["projeto_id = ? and usuario_id = ?", 0, @projeto.responsavel_td.to_i])
    if @permissaoAvancado2.nil?
    if @permissaoI.nil?
      @permissaoIn = Permissao.new(params[:permissao])
# else
# @permissaoIn = @permissaoI
# end
    @permissaoIn.usuario = Usuario.find(:first, :conditions => ["id =
?", @projeto.responsavel_td.to_i])
    @permissaoIn.projeto = Projeto.find(:first, :conditions => ["id =
?", @projeto.id])
    @permissaoIn.perfil = "Intermediário"
# if !@permissaoI.nil?
# @permissaoIn.update_attributes(params[:permissao])
# else
    @permissaoIn.save(params[:permissao])
    if !@permissoesB.empty?
      for perm in @permissoesB
        perm.destroy
      end
    end
    end
    end

    @permissaoB = Permissao.find(:first, :conditions => ["projeto_id = ?
and perfil = ? and usuario_id = ?", @projeto.id, "Básico",
@projeto.coordenador.to_i])
    @permissaoAvancado3 = Permissao.all(:conditions => ["projeto_id = ?
and usuario_id = ?", 0, @projeto.coordenador.to_i])
    @permissoesI = Permissao.all(:conditions => ["projeto_id = ? AND
usuario_id = ? AND perfil = ?", @projeto.id, @projeto.coordenador.to_i,
"Intermediário"])
    ## Se ele já tiver a permissao de avançado, não faz nada. Se não
tiver, cria uma (sem nenhum projeto)
    if @permissaoAvancado3.empty? && @permissoesI.empty?
# if @permissaoB.nil?
      @permissaoBa = Permissao.new(params[:permissao])
# else
# @permissaoBa = @permissaoB
# end
    @permissaoBa.usuario = Usuario.find(:first, :conditions => ["id =
?", @projeto.coordenador.to_i])
    @permissaoBa.projeto = Projeto.find(:first, :conditions => ["id =
?", @projeto.id])
    @permissaoBa.perfil = "Básico"
# if !@permissaoB.nil?
# @permissaoBa.update_attributes(params[:permissao])
# else
      @permissaoBa.save(params[:permissao])
# end
    end

    ## Ao editar um projeto, existe a possibilidade da alteração do
responsável pela Td
    ## Portanto, ele procura por todas as tarefas daquele projeto
    @tarefas = Tarefa.all(:conditions => ["projeto_id = ?",
@projeto.id])
    ## Varre cada uma
    for tarefa in @tarefas
    ## Altera o campo "responsável" pelo respnsável_td recém modificado
(ou não) na edição do projeto
      tarefa.responsavel = Usuario.find(:first, :conditions => ["id =
?", @projeto.responsavel_td]).nome
    ## Atualiza as alterações
      tarefa.update_attributes(params[:tarefa])
    end
        flash[:msg] = "Projeto atualizado com sucesso"
        redirect_to(@projeto)
   else
      render :action => "edit"
    end
  end
[/code]

It works ok, but what i wanna do is:

destroy the "permissao" of "responsavel_td" and "coordenador" BEFORE the
update.
in other words, if the "responsavel_td" or the "coordenador" change, i
wanna to destroy the "permissao" existing for those who were before the
change.

I make my self clear?

If you can't understand me, just think this way.. How can I return the
value before the update?

Thanks any help.

Hi.

I have the following controller of the update action:

[code]
def update
@projeto = Projeto.find(params[:id])

if (@projeto.update_attributes(params[:projeto]))

## Mesmo raciocínio utilizado no create.
@permissaoA = Permissao.find(:first, :conditions => ["usuario_id =
?", @projeto.responsavel.to_i])
@permissaoAvancado1 = Permissao.find(:first, :conditions =>
["projeto_id = ? and usuario_id = ?", 0, @projeto.responsavel.to_i])
if @permissaoAvancado1.nil?
## Caso tenham excluido os usuários responsáveis, as permissões
seriam nulas. Dai ele verifica se vai alterar ou criar uma permissão
if @permissaoA.nil?
@permissaoAv = Permissao.new(params[:permissao])
@permissaoAv.perfil = "Avançado"
@permissaoAv.usuario = Usuario.find(:first, :conditions => ["id =
?", @projeto.responsavel.to_i])
@permissaoAv.save(params[:permissao])
end
end

## O mesmo que avançado
@permissaoI = Permissao.find(:first, :conditions => ["projeto_id = ?
and perfil = ? and usuario_id = ?", @projeto.id, "Intermediário",
@projeto.responsavel_td.to_i])
@permissoesB = Permissao.all(:conditions => ["projeto_id = ? and
usuario_id = ? and perfil = ?", @projeto.id,
@projeto.responsavel_td.to_i, "Básico"])
@permissaoAvancado2 = Permissao.find(:first, :conditions =>
["projeto_id = ? and usuario_id = ?", 0, @projeto.responsavel_td.to_i])
if @permissaoAvancado2.nil?
if @permissaoI.nil?
@permissaoIn = Permissao.new(params[:permissao])
# else
# @permissaoIn = @permissaoI
# end
@permissaoIn.usuario = Usuario.find(:first, :conditions => ["id =
?", @projeto.responsavel_td.to_i])
@permissaoIn.projeto = Projeto.find(:first, :conditions => ["id =
?", @projeto.id])
@permissaoIn.perfil = "Intermediário"
# if !@permissaoI.nil?
# @permissaoIn.update_attributes(params[:permissao])
# else
@permissaoIn.save(params[:permissao])
if !@permissoesB.empty?
for perm in @permissoesB
perm.destroy
end
end
end
end

@permissaoB = Permissao.find(:first, :conditions => ["projeto_id = ?
and perfil = ? and usuario_id = ?", @projeto.id, "Básico",
@projeto.coordenador.to_i])
@permissaoAvancado3 = Permissao.all(:conditions => ["projeto_id = ?
and usuario_id = ?", 0, @projeto.coordenador.to_i])
@permissoesI = Permissao.all(:conditions => ["projeto_id = ? AND
usuario_id = ? AND perfil = ?", @projeto.id, @projeto.coordenador.to_i,
"Intermediário"])
## Se ele já tiver a permissao de avançado, não faz nada. Se não
tiver, cria uma (sem nenhum projeto)
if @permissaoAvancado3.empty? && @permissoesI.empty?
# if @permissaoB.nil?
@permissaoBa = Permissao.new(params[:permissao])
# else
# @permissaoBa = @permissaoB
# end
@permissaoBa.usuario = Usuario.find(:first, :conditions => ["id =
?", @projeto.coordenador.to_i])
@permissaoBa.projeto = Projeto.find(:first, :conditions => ["id =
?", @projeto.id])
@permissaoBa.perfil = "Básico"
# if !@permissaoB.nil?
# @permissaoBa.update_attributes(params[:permissao])
# else
@permissaoBa.save(params[:permissao])
# end
end

## Ao editar um projeto, existe a possibilidade da alteração do
responsável pela Td
## Portanto, ele procura por todas as tarefas daquele projeto
@tarefas = Tarefa.all(:conditions => ["projeto_id = ?",
@projeto.id])
## Varre cada uma
for tarefa in @tarefas
## Altera o campo "responsável" pelo respnsável_td recém modificado
(ou não) na edição do projeto
tarefa.responsavel = Usuario.find(:first, :conditions => ["id =
?", @projeto.responsavel_td]).nome
## Atualiza as alterações
tarefa.update_attributes(params[:tarefa])
end
flash[:msg] = "Projeto atualizado com sucesso"
redirect_to(@projeto)
else
render :action => "edit"
end
end
[/code]

It works ok, but what i wanna do is:

destroy the "permissao" of "responsavel_td" and "coordenador" BEFORE the
update.
in other words, if the "responsavel_td" or the "coordenador" change, i
wanna to destroy the "permissao" existing for those who were before the
change.

I make my self clear?

No, not to me anyway, the code and question are too complex. Try to
reduce your question to to it's basic requirement. Explain what you
want to do simply rather than providing large amounts of (mostly)
irrelevant code that would take too much time for the reader to
understand.

If you can't understand me, just think this way.. How can I return the
value before the update?

That is a much simpler question, but does not make sense as a
standalone question

Colin

I'm in edit page, ok?

I change something and then i submit and update.

What I wanna know is:

How can I return the value that exists BEFORE I update the changes?
Without losing the changes.

Now am I clear?

Much better, though still not sure about what you mean by 'return' the
value that exists... Where are you returning it from and to? If you
mean that in the update action of the controller you want to access
the current value of the record in the db before saving the new
values, then, assuming that you are using the normal method like
@record = MyModel.find(params[:id])
if @record.update_attributes(params[:sample])
Then between those two lines @record has the original values from the
db. update_attributes picks up the data from params and updates the
db.

Colin

Colin Law wrote:

Now am I clear?

Much better, though still not sure about what you mean by 'return' the
value that exists... Where are you returning it from and to? If you
mean that in the update action of the controller you want to access
the current value of the record in the db before saving the new
values, then, assuming that you are using the normal method like
@record = MyModel.find(params[:id])
if @record.update_attributes(params[:sample])
Then between those two lines @record has the original values from the
db. update_attributes picks up the data from params and updates the
db.

Colin

Just a point that I've always found slightly confusing. If I've
understood correctly this line..

if @record.update_attributes(params[:sample])

actually *does* the updating part, believe the if is there for error
trapping and returning.

I've always struggled as to why that line starts with the word "if", am
I reading it right in that the line basically does the update_attributes
"if" it can? Maybe I'm just thinking about it wrong but it doesn't seem
intuitive to me.

Yes, it returns true if the save succeeds. You could have answered
this yourself easily by looking at the docs.
http://api.rubyonrails.org/classes/ActiveRecord/Base.html

Colin

I will try to put the code between those lines, thanks.

I've done this:

def update
    @projeto = Projeto.find(params[:id])

## Here it finds one "permissao" with the user that i choose, the
profile that i choose and the project that i choose.
    @ex_permissaoI = Permissao.find(:first, :conditions => ["usuario_id
= ? and perfil = ? and projeto_id = ?", Usuario.find(:first, :conditions
=> ["id = ?", @projeto.responsavel_td.to_i]), "Intermediário",
@projeto.id])
    @ex_permissaoB = Permissao.find(:first, :conditions => ["usuario_id
= ? and perfil = ? and projeto_id = ?", Usuario.find(:first, :conditions
=> ["id = ?", @projeto.coordenador.to_i]), "Intermediário",
@projeto.id])
## Here it should destroy those "permissao"
    @ex_permissaoI.destroy
    @ex_permissaoB.destroy

    if (@projeto.update_attributes(params[:projeto]))
(...)
end

And I get this error:

You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.destroy

Bla ... wrote:

I've done this:

def update
    @projeto = Projeto.find(params[:id])

## Here it finds one "permissao" with the user that i choose, the
profile that i choose and the project that i choose.
    @ex_permissaoI = Permissao.find(:first, :conditions => ["usuario_id
= ? and perfil = ? and projeto_id = ?", Usuario.find(:first, :conditions
=> ["id = ?", @projeto.responsavel_td.to_i]), "Intermediário",
@projeto.id])
    @ex_permissaoB = Permissao.find(:first, :conditions => ["usuario_id
= ? and perfil = ? and projeto_id = ?", Usuario.find(:first, :conditions
=> ["id = ?", @projeto.coordenador.to_i]), "Intermediário",
@projeto.id])
## Here it should destroy those "permissao"
    @ex_permissaoI.destroy
    @ex_permissaoB.destroy

    if (@projeto.update_attributes(params[:projeto]))
(...)
end

And I get this error:

You have a nil object when you didn't expect it!
You might have expected an instance of ActiveRecord::Base.
The error occurred while evaluating nil.destroy

Well, which @ex_permissao is the nil one? Obviously, one or both of
your finds are failing. You should try running that code in irb to make
sure that the conditions you are constructing are actually returning
something.

bingo bob wrote:
[...]

Just a point that I've always found slightly confusing. If I've
understood correctly this line..

if @record.update_attributes(params[:sample])

actually *does* the updating part, believe the if is there for error
trapping and returning.

I've always struggled as to why that line starts with the word "if", am
I reading it right in that the line basically does the update_attributes
"if" it can? Maybe I'm just thinking about it wrong but it doesn't seem
intuitive to me.

You are indeed thinking about it completely wrong. Think in the general
case about how
if EXPR
works in Ruby: it evaluates EXPR and then looks to see if it returns
true or false. So
if x > 5
evaluates x > 5 and checks its return value.

Likewise,
if @record.update_attributes(params[:sample])
evaluates @record.update_attributes(params[:sample]) and checks its
return value. It *happens* that in the course of the evaluation, a
database operation is attempted, but that's immaterial to the if
statement.

Best,

Marnen,

that makes an awful lot of things more clear - thanks for taking the
time :-).