How to use two attributes in one validates_inclusion_of stat


#1

Hey hey :slight_smile:

Might be a dumb-ass question, but then please bear with me.

I’m trying to add these two validations to a model:

validates_inclusion_of(:controller, :in => controllers, :message =>
‘does not exist in this application’)
validates_inclusion_of(:action, :in =>
controllers[:action], :message => ‘is not implemented in the specified
controller’)

Basically, controllers is a method that creates a hash of all
controllers in my application, and an array of method names for each
hash entry. The method works fine, and queries work like I would
expect, e.g.,
c = controllers => {“store”=>[“index”, “list”, “search”,
“show”], "a…
c.include? ‘store’ => true
c[‘store’].include? ‘index’ => true

The first validates_inclusion_of works fine. But I don’t know how to
get the second validates_inclusion_of to use the value of the action
attribute on the object in question. I’ve tried :action, action,
@action, and @@action, but none of them contain the value of the
action attribute on the object that I’m working on. How can I get to
that attribute and use it in my validation statement above?

Thank you very much for any help :slight_smile:

Daniel


#2

Jason R. wrote:

Could try params[:action] though I’m not sure if that’s available to you at
that time.

Jason

Not really, as it’s on the model level. Thanks, though :slight_smile:


#3

Could try params[:action] though I’m not sure if that’s available to you
at
that time.

Jason


#4

self.bonk!

Yeah, missed that. This might just need to be controller-side
validation. In
terms of MVC architecture, the model should know nothing about the state
of
the controller.

Jason


#5

Jason R. wrote:

self.bonk!

LOL :slight_smile:

Yeah, missed that. This might just need to be controller-side validation. In
terms of MVC architecture, the model should know nothing about the state of
the controller.

Yes, but it is not in the controller - both attributes are on the
model. I want to check that the :controller value indeed matches an
existing controller, and then, that the :action matches an action
implemented in this controller. But to do the latter (the former works
fine right now), I need to check my self-created controller hash at
the correct index - like this,

validates_inclusion_of(:action, :in =>
controllers[:controller], :message => ‘is not implemented in the
specified controller’)

Except that I don’t know how to get the value in the :controller
attribute. Nothing I can think of writing yields that value… Do I
make any sense? Here’s the entire model:

== Schema Information

Schema version: 6

Table name: navigation_points

id :integer(11) not null, primary key

parent_id :integer(11)

controller :string(255) default(), not null

action :string(255) default(index), not null

name_da :string(255) default(), not null

name_en :string(255) default(), not null

class NavigationPoint < ActiveRecord::Base

acts_as_tree :order => ‘action’, :counter_cache => :children_count

validates_presence_of :controller,
:action,
:name_da,
:name_en

validates_inclusion_of(:controller, :in => controllers, :message =>
‘does not exist in this application’)
validates_inclusion_of(:action, :in =>
controllers[:controller], :message => ‘is not implemented in the
specified controller’)

end

And here’s my ‘controllers’ method, which is a library function:

Generates a 2D array of all possible controllers and their methods

in the application.
def controllers

Suck in all controllers:

require ‘find’
Find.find(File.join(RAILS_ROOT, ‘app/controllers’)) { |name|
require_dependency(name) if /_controller.rb$/ =~ name
}

Consume all classes in a hash:

@classes = {}
ObjectSpace.subclasses_of(ActionController::Base).each do |obj|
@classes["#{obj.controller_name}"] = obj
end

Iterate over the hash, and create our controllers hash:

controllers = Hash.new()
@classes.each_value { |c|
# Add the controller name:
controllers["#{c.controller_name}"] = []
# Add all methods under the controller:
@methods = c.public_instance_methods(false) # This one gets all
methods, even hidden ones.
@methods.sort.each { |m|
controllers["#{c.controller_name}"] << m.to_s
}
}

Return the array

controllers
end

Cheers,
Daniel :slight_smile: