Ruby Forum Rails Germany > validate via method-chain überladen

Posted by Jan Luehr (Guest)
on 01.05.2008 22:04
(Received via mailing list)
ja hallo erstmal,..

ich stehe hier vor einem kleinen Problem.
Ich möchte gerne gemeinsam genutzte Validierungsroutinen in einen helper
auslagern und dann includieren. Der helper sieht so aus:

module AliastestHelper
  alias_method :orig_validate, :validate
  def validate
    errors.add_to_base("Helper included")
    orig_validate
  end
end

Wenn ich ihn einbinden, wird folgende Exception geworfen:
undefined method `validate' for module `AliastestHelper'

Ich stehe gerade ein wenig wie der Ochs vor dem Berg - warum wird die 
Methode
validate im helper nicht gefunden?

Danke,
Keep smiling
yanosz
Posted by Thomas R. Koll (Guest)
on 01.05.2008 22:13
(Received via mailing list)
Hi Jan,

Ich vermute mal dass alias_method erst dann Sinn macht wenn das Module
inkludiert wird. Ohne testen, aber es sollte etwa in diese Richtung
gehen.

module AliastestHelper
   def included
     alias_method :orig_validate, :validate
   end
   ...
end

ciao, tom

Am 01.05.2008 um 22:03 schrieb Jan Luehr:
>     errors.add_to_base("Helper included")
>     orig_validate
>   end
> end
>
> Wenn ich ihn einbinden, wird folgende Exception geworfen:
> undefined method `validate' for module `AliastestHelper'


--
Thomas R. "TomK32" Koll || http://tomk32.de || http://ananasblau.com
just a geek trying to change the world
Skype: TomK32 || Mail: tomk32@gmx.de
Posted by Michael Schuerig (Guest)
on 01.05.2008 23:09
(Received via mailing list)
On Thursday 01 May 2008, Thomas R. Koll wrote:

> Ich vermute mal dass alias_method erst dann Sinn macht wenn das
> Module inkludiert wird. Ohne testen, aber es sollte etwa in diese
> Richtung gehen.
>
> module AliastestHelper
>    def included
>      alias_method :orig_validate, :validate
>    end
>    ...
> end

module AliastestHelper
  def self.included(base)
    base.send(:extend, InstanceMethods)
    alias_method_chain :validate, :foo
  end
  def validate_with_foo
    ...
    validate_without_foo
  end
end

Das halte ich aber, ohne weitere Kenntnis des genauen Problems, 
für keine gute Lösung.

[Jan Luehr:]
> ich stehe hier vor einem kleinen Problem.
> Ich möchte gerne gemeinsam genutzte Validierungsroutinen in einen
> helper auslagern und dann includieren. Der helper sieht so aus:

Man kann Validierungen auch quasi-deklarativ definieren:

module CommonValidations
  def that_foo_is_not_bar
  end
end

class MyValidations
  def self.validate
  end
end

class MyModel < ActiveRecord::Base
  include CommonValidations
  validate :that_foo_is_not_bar
  validate MyValidations
  validate proc { |record| ... }
end

Wenn es ganz schön werden soll, kannst du eigene Validierungsmethoden
definieren:

# lib/my_validations.rb
module MyValidations
  def self.included(base)
    base.extend(ClassMethods)
  end

  module ClassMethods
    def validates_foobar(options = {})
      send(validation_method(options[:on] || :save)) do |record|
        unless (options[:if] &&
            !evaluate_condition(options[:if], record)) ||
            (options[:unless] &&
            evaluate_condition(options[:unless], record))
          if something_bad
            record.errors.add_to_base("foobar is foobar'ed")
          end
        end
      end
    end
  end
end

# config/initializers/my_validations.rb
require 'my_validations'
ActiveRecord::Base.class_eval do
  include MyValidations
end

# app/models/my_model
class MyModel < ActiveRecord::Base
  validates_foobar
end

Vorsicht! Ich habe dieses Beispiel nicht ausprobiert, sondern freihändig
von einem ähnlichen Fall in einem meiner Projekte angepasst. Wenn es
nicht auf Anhieb funktioniert, dann liegt's an mir.

Michael

--
Michael Schuerig
mailto:michael@schuerig.de
http://www.schuerig.de/michael/