Forum: Ruby on Rails variable variables?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Daniel H. (Guest)
on 2006-04-16 07:20
(Received via mailing list)
Hi everyone,

Does Ruby support variable variables like PHP
(http://www.php.net/manual/en/language.variables.variable.php)? Or do I
have
to use eval, like

some_hash.each_pair{|key, pair|
	eval "#{key} = #{value}"
}

Or is there some other way?

I'm actually trying to figure this out in order to use ez_where to
create
its conditions from a hash, so if this isn't even necessary could
someone
let me know?

Thanks,
Daniel
Ezra Z. (Guest)
on 2006-04-16 07:29
(Received via mailing list)
On Apr 15, 2006, at 8:17 PM, Daniel H. wrote:

>
> Or is there some other way?
>
> I'm actually trying to figure this out in order to use ez_where to
> create
> its conditions from a hash, so if this isn't even necessary could
> someone
> let me know?
>
> Thanks,
> Daniel

Daniel-

	There is already support for hash.to_sql and other niceties included
in ez_where. Like so:

class Hash #:nodoc:
   def to_sql(param = 'AND')
     map { |key,value| key.to_s+' = '+ActiveRecord::Base.send
(:sanitize, value) }.join(' '+param+' ')
   end

   def to_conditions(param = 'AND')
     [map { |k, v| k.to_s+' = ?' }.join(' '+param+' '), *values]
   end

   alias :to_sql_conditions :to_conditions
   def to_named_conditions(param = 'AND')
     [map { |k, v| k.to_s+' = :'+k }.join(' '+param+' '),
self.symbolize_keys]
   end

end

Look in lib/hash.rb for this. Also the best way to see what that
plugin is capable of is looking at the test suite. The
ez_where_tests.rb file in the plugin is 700 lines long and exercises
all the capabilities of the plugin. So you can see many many sample
codes using the plugin in that tests file. Its the most complete
documentation on it right now ;)

Cheers-
-Ezra
Daniel H. (Guest)
on 2006-04-16 08:12
(Received via mailing list)
Hi Ezra,

Thanks for your response!

Let's say I'm trying to collect old gambling debts and want to find
people
who owe me money within a range of values, and  who live in certain
cities.
My hash looks something like

search {
	:location_ids => [0, 8, 10]
	:amount_owed =>
		{:from => 5000, :to => 10000}
	:still_alive => 'true'
}

I've looked through the tests file and wasn't able to gain any insight
into
how I could convert a hash like this into a nice string of conditions.
I'm
imagining something like, to start with,

cond = Caboose::EZ::Condition.new :chumps do
	search.each_pair {|key, value|
		if defined? value[:from]
			eval "#{key} >= #{value[:from]}"
			next
		end
	end
end

But the more I look at that code the more ridiculous it seems. Any
ideas?

Thanks again for your help!

Daniel
Daniel H. (Guest)
on 2006-04-16 13:45
(Received via mailing list)
One difficulty I found with Hash#to_sql was that if values in the hash
were
empty you could end up with something like "seller_id = 3 AND AND views
=
45"

>From what I understand, though, part of the Ruby Way is to have many little
method that do one thing, so I should make method that strips out all
empty
values first and pass the result to one of the new Hash methods.

I didn't think about that until just now, though. In the mean time I
made
the following, which hopefully someone will find useful:

  def conditions_from_hash(some_hash)
    condition = ''
    some_hash.each_pair {|key, value|
      if value.empty?
        next
      elsif (value.class == Hash) && value.values.inject{|total,
current| \
total+current}.empty?
        next
      elsif (value.class == Array)
        if value.inject{|total, current| total+current}.empty?
          next
        elsif /(.*)_ids$/.match(key)
          condition << "#{key[0...-4].pluralize}.`id` IN(" << \
value.join(',') << ") AND "
        end
      elsif value[:from] || value[:to]
        condition << "#{key} >= #{value[:from]} AND " unless \
value[:from].empty?
        condition << "#{key} <= #{value[:to]} AND " unless
value[:to].empty?
      else
        condition << "#{key} LIKE '%#{value}%' AND "
      end
    }
    condition[0..-5].to_s
  end

It's pretty much particular to what I'm trying to do, so it doesn't have
niceties like a "param" argument. What I'm trying to do is perform a
search
based on input which includes a range (<input
name="search[price][from]">
and <input search[price][to]) and a bunch of category checkboxes
(<checkbox
name="genre_ids[]">) . I wanted to keep the form of the code general
enough
to allow me to use it for other controllers in the site with the same
needs.

Daniel
This topic is locked and can not be replied to.