In the rails application, when the table structure is complex, i often have many ways to access the database to get the data, such as using several attributes.
For example,
table :person column :nickname
column :hobbies column :constellation …
I have to write several methods to fit for the requirement. For example, get_personal_by_nickname, get_personal_by_nickname_with_hobbies, so on.
So I wrote a function, using a condition map to do the mapping. like
module ActiveRecord class Base class << self # generate the query conditions due to the CMAP
def generate_query(options = {})
includes, conditions = Array.new, Array.new
options.each do |key, value|
begin
if (@CMAP.has_key?(key) && !value.nil?)
case @CMAP[key][0]
when Symbol
includes << @CMAP[key][0]
when Hash
includes << @CMAP[key][0][value.to_sym]
end
case @CMAP[key][1]
when String
conditions << @CMAP[key][1] if @CMAP[key][1]
when Hash
conditions << @CMAP[key][1][value.to_sym
] if @CMAP[key][1] end end rescue NameError $stderr.print “you should define @CMAP attribute for the query_generator” + $! raise end
end
[includes, conditions]
end
end
In the specific model, @CMAP is defined as, for example, @CMAP = { :nickname => [:include, “nickname = :nickname”],
:hobbies => [:include, “hobbies = :hobbies”], … }
Then using hash as a param and get the generated query.
But this way i need to take care of @CMAP, indeed sometimes it can’t fit my requirement either.
Is there a better way to do the work? How do you guys work this?
thx.