Validierung basierend auf der ID der Drop-Down-Box in den Schienen - Ruby-on-Rails, Ruby, Rails-ActiveRecord

Ich habe eine Validierung während des Eingabevorgangs wie folgt:

validates :solids, :numericality => { :greater_than_or_equal_to => 0 }, :if => lambda {
if self.lab_method_id
lab_method = LabMethod.find(self.lab_method_id)
lab_method.solids?
end
}

Ich möchte diese Bedingung basierend auf der ausgewählten ID einer Dropdown-Box ändern.

Ich habe das in meinem Modell versucht:

if self.lab_method_id == 1
validates :solids, :numericality => { :greater_than_or_equal_to => 0 }, :if => lambda {
if self.lab_method_id
lab_method = LabMethod.find(self.lab_method_id)
lab_method.solids?
end
}
elsif
validates :solids, :numericality => { :greater_than_or_equal_to => 5 }, :if => lambda {
if self.lab_method_id
lab_method = LabMethod.find(self.lab_method_id)
lab_method.solids?
end
}
end

Dies hat jedoch den Fehler beim Laden der Seite zurückgegeben:

undefinierte Methode `key? 'für nil: NilClass

Ich vermutete, dass dies mit der Tatsache zu tun hatte, dass dieValidierungen im Modell werden beim Laden der Seite geladen, und dies würde nicht funktionieren, wenn eine if-Anweisung nach der ID sucht. Obwohl dieser Fehler für mich keinen Sinn ergibt.

Also frage ich mich, wie ich es so einrichten soll, dass die spezifische Validierung basierend auf der ID des ausgewählten Drop-Down-Box-Elements gewählt wird (bekomme ich sogar die ID richtig)?

Bonus: Könnte jemand die Beziehung zu diesem speziellen Fehler erklären?

BEARBEITEN - Stack-Trace:

vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / aktionscontroller / metal / hide_actions.rb: 36: in visible_action?" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_controller/metal/hide_actions.rb:18:inmethod_for_action " vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / aktionscontroller / metal / implizit_render.rb: 14: in method_for_action" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_controller/metal/compatibility.rb:61:inmethod_for_action " vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / abstract_controller / base.rb: 115: in process" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/abstract_controller/rendering.rb:45:inverarbeiten" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / action_controller / metal.rb: 203: in dispatch" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_controller/metal/rack_delegation.rb:14:inVersand" Verkäufer / Bündel / Rubin / 1.9.1 / gems / Action-3.2.1 / lib / action_controller / metal.rb: 246: in block in action" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/routing/route_set.rb:66:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / action_dispatch / routing / route_set.rb: 66: in dispatch" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/routing/route_set.rb:30:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ journey-1.0.4 / lib / journey / router.rb: 68: in block in call" vendor/bundle/ruby/1.9.1/gems/journey-1.0.4/lib/journey/router.rb:56:injeder" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ journey-1.0.4 / lib / journey / router.rb: 56: in call" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/routing/route_set.rb:589:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ warden-1.2.1 / lib / warden / manager.rb: 35: in block in call" vendor/bundle/ruby/1.9.1/gems/warden-1.2.1/lib/warden/manager.rb:34:inFang" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ warden-1.2.1 / lib / warden / manager.rb: 34: in call" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/best_standards_support.rb:17:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ rack-1.4.1 / lib / rack / etag.rb: 23: in call" vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/conditionalget.rb:25:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / action_dispatch / middleware / head.rb: 14: in call" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/params_parser.rb:21:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / action_dispatch / middleware / flash.rb: 242: in call" vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/session/abstract/id.rb:205:inKontext" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ rack-1.4.1 / lib / rack / session / abstract / id.rb: 200: in call" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/cookies.rb:338:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ activecord-3.2.1 / lib / active_record / query_cache.rb: 64: in call" vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:443:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / action_dispatch / middleware / callbacks.rb: 28: in block in call" vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.1/lib/active_support/callbacks.rb:405:inLauf_803795940_Anruf_68852270__callbacks " vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ activesupport-3.2.1 / lib / active_support / callbacks.rb: 405: in __run_callback" vendor/bundle/ruby/1.9.1/gems/activesupport-3.2.1/lib/active_support/callbacks.rb:385:in_run_call_callbacks " vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ activesupport-3.2.1 / lib / active_support / callbacks.rb: 81: in run_callbacks" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/callbacks.rb:27:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / action_dispatch / middleware / reloader.rb: 65: in call" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/remote_ip.rb:31:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / action_dispatch / middleware / debug_exceptions.rb: 16: in call" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/show_exceptions.rb:56:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ railties-3.2.1 / lib / rails / rack / logger.rb: 26: in call_app" vendor/bundle/ruby/1.9.1/gems/railties-3.2.1/lib/rails/rack/logger.rb:16:inAnruf" config / initializers / quiet_assets.rb: 6: in call_with_quiet_assets" vendor/bundle/ruby/1.9.1/gems/actionpack-3.2.1/lib/action_dispatch/middleware/request_id.rb:22:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ rack-1.4.1 / lib / rack / methodoverride.rb: 21: in call" vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/runtime.rb:17:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / gems / activesupport-3.2.1 / lib / aktiver_support / cache / strategie / local_cache.rb: 72: in call" vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/lock.rb:15:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ actionpack-3.2.1 / lib / action_dispatch / middleware / static.rb: 53: in call" vendor/bundle/ruby/1.9.1/gems/railties-3.2.1/lib/rails/engine.rb:479:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / edelsteine ​​/ railties-3.2.1 / lib / rails / application.rb: 220: in call" vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/content_length.rb:14:inAnruf" vendor / bundle / ruby ​​/ 1.9.1 / gems / railties-3.2.1 / lib / rails / rack / log_tailer.rb: 14: in call" vendor/bundle/ruby/1.9.1/gems/rack-1.4.1/lib/rack/handler/webrick.rb:59:inBedienung" /usr/lib/ruby/1.9.1/webrick/httpserver.rb:138:in service" /usr/lib/ruby/1.9.1/webrick/httpserver.rb:94:inLauf" /usr/lib/ruby/1.9.1/webrick/server.rb:191:in `block in start_thread"

Antworten:

1 für die Antwort № 1

NumericalityValidator (der zugrunde liegende Validierer für diesen Helper) funktioniert nicht mit dynamischen Bedingungen, wie Sie möchten. Verwenden Sie einen benutzerdefinierten Validierer:

validate :solids_validation

def solids_validation
if self.lab_method_id
lab_method = LabMethod.find(self.lab_method_id)
if lab_method.solids?
if (val = Kernel.Float(solids) rescue nil)
min = (self.lab_method_id == 1 ? 0 : 5)
errors.add(:solids, "must be greater than or equal to #{min}") if val < min
else
errors.add(:solids, :not_a_number)
end
end
end
end

Speisekarte