sobreescrevendo um método vindo de um has-many

5 views
Skip to first unread message

Bruno Reis

unread,
Dec 11, 2007, 7:12:08 AM12/11/07
to rail...@googlegroups.com
Eu tenho um modelo que tem a seguinte declaração:
belongs_to :extra, :polymorphic=>true 
então neste modelo eu tenho um método de nome
extra que veio com a própria associação.
Como eu faço para sobreescrever este método e chamar o original?

quero fazer algo do tipo:

def extra
  self.criar_extra if (self.extra.nil?)
  extra ### <- Chamada ao método original que havia sido criado pela associação
end

Esta parte em negrito que eu não sei como fazer pra chamar o método que eu sobreescrevi.
Alguém sabe?

Valeu,
Bruno Reis

Felipe Mathies

unread,
Dec 11, 2007, 8:43:51 AM12/11/07
to rail...@googlegroups.com
cara naum sei se eh o teu caso, mas podes fazer um aliase do metodo original desta maneira

alias :original_extra :extra
def extra
original_extra # chama o metodo original :)
end


--
Felipe Mathies
msn: felipe...@hotmail.com
skype: voorhees1986
blog : http://felipemathies.blogspot.com

hallison.batista

unread,
Dec 12, 2007, 9:05:49 AM12/12/07
to rails-br
Olá Bruno.

Se não me engano, existe um método chamado "alias_method" na classes
Module, que faz uma "cópia" do método original.
Ele é utilizado pelo plugin BrazilianRails para a composição
"usar_como_dinheiro". Faça como o Felipe mencionou, mas utilizando o
"alias_method":

alias_method :extra_original :extra

def extra
original_extra # para chamara o método original
end

Espero ter ajudado.

Um abraço

Hallison Batista

hallison.batista

unread,
Dec 13, 2007, 1:42:36 PM12/13/07
to rails-br
Olá Bruno.

Somente para correção:

alias_method :extra_original, :extra

def extra
extra_original # para chamara o método original
end

Um abraço.

Hallison Batista

On 12 dez, 10:05, "hallison.batista" <hallison.bati...@gmail.com>
wrote:

Bruno Reis

unread,
Dec 14, 2007, 4:32:19 PM12/14/07
to rail...@googlegroups.com
Valeu pessoal, mas e no caso de ser um método de classe, estático?

eu achei na net da seguinte maneira (que confesso que não sei bem o que significa) ...

class << self
    alias_method :new_new, :new
end

#validates_presence_of :conteudo_estado_id,:user_id
def self.new
    raise "Deve ser criado pelo factory - Conteudo::criar_topo_hierarquia ou conteudo.criar"
end

Mas aí quando eu chamo Class.new_new ele chama o new e da um 'raise' no erro mesmo assim.

O que eu quero realmente é fazer com que a classe, um model, não possa ter seu método new chamado diretamente. Quero deixar isso em um contexto privado e gerar um método público que por sua vez chama o new e inicializa algumas variáveis (tipo um factory). Alguém sabe como fazer isso?

Bruno

Em 13/12/07, hallison.batista <hallison...@gmail.com> escreveu:

hallison.batista

unread,
Dec 17, 2007, 8:55:18 PM12/17/07
to rails-br
Olá Bruno.

Em contraste, crie o alias para o método initialize.

class << self
alias_method :initialize_original initialize
end

O método new chama o initialize por default (teoria sobre Ruby). Não
há um método chamado new.

Entretanto, eu não aconselho você fazer isso. Você deve ser
programador Java (como eu). Primeiro, não desenvolva utilizando as
técnicas e "leis de desenvolvimento" "impostas" pelo Java.

Não faça factory onde não há necessidade. Lembre-se que Ruby é uma
linguagem dinâmica. Em qualquer lugar do código, alguém pode sobre-
escrever seu método "factory". Crie um método de classe que retorne a
instância como você deseja. Exemplo:

class << self
def novo_com_atributos_filtrados(outros_atributos)
outros_atributos.each do |atributo|]
# filtro dos atributos
end
self.new(outros_atributos)
end
end

O exemplo é meio sem sentido, mas eu creio que você captou a idéia.

Tenho um caso de uso: FormularioModelo e FormularioAvaliacao. Há um
cadastro de FormularioModelo (CRUD) e um de FormularioAvaliacao
(semelhante ao caso de uso de Notas Fiscais) para gerar históricos. O
FormularioAvaliacao copia parte dos atributos de FormularioModelo.
Então criei um método de classe que realiza essa cópia (apesar de o
Rails já oferecer um método clone). Vamos explorar o máximo da
flexibilidade de Ruby.

Espero ter ajudado.

Hallison Batista

On 14 dez, 17:32, "Bruno Reis" <bruno.p.r...@gmail.com> wrote:
> Valeu pessoal, mas e no caso de ser um método de classe, estático?
>
> eu achei na net da seguinte maneira (que confesso que não sei bem o que
> significa) ...
>
> class << self
> alias_method :new_new, :new
> end
>
> #validates_presence_of :conteudo_estado_id,:user_id
> def self.new
> raise "Deve ser criado pelo factory - Conteudo::criar_topo_hierarquia ou
> conteudo.criar"
> end
>
> Mas aí quando eu chamo Class.new_new ele chama o new e da um 'raise' no erro
> mesmo assim.
>
> O que eu quero realmente é fazer com que a classe, um model, não possa ter
> seu método new chamado diretamente. Quero deixar isso em um contexto privado
> e gerar um método público que por sua vez chama o new e inicializa algumas
> variáveis (tipo um factory). Alguém sabe como fazer isso?
>
> Bruno
>
> Em 13/12/07, hallison.batista <hallison.bati...@gmail.com> escreveu:

Bruno Reis

unread,
Dec 18, 2007, 5:54:55 AM12/18/07
to rail...@googlegroups.com
Hallison,

Grato. Essa parte eu fiz assim mesmo. Mas o que eu quero fazer é melhorar a interface do meu modelo de forma a não permitir que um outro programador chame o método new. O problema é que se eu sobreescrevo o new, aí eu não consigo instanciar o objeto no método que vai cria-lo.

Bruno

Em 17/12/07, hallison.batista <hallison...@gmail.com> escreveu:
Reply all
Reply to author
Forward
0 new messages