Here is one option that seems to technically answer your question, but I assume this is not what you are looking for:
params.select{|_,v| v.strip.length > 0 if v}
The main problem that you are facing is that the Hash # card does not support a hash, but rather an array. Many people, including me, find this annoying. See for example: http://www.ruby-forum.com/topic/185611
Here is a detailed option using injection.
params.inject({}) {|h,(k,v)| h.merge(k => v ? v.strip : v)}.select{|_,v| v.length > 0 if v}
If this matters to you, none of these solutions will lead to any destructive parameter changes.
1.9.3-p125 :030 > params = {:email => " ab", :xyz => " ", :opq => nil} => {:email=>" ab", :xyz=>" ", :opq=>nil} 1.9.3-p125 :031 > params.inject({}) {|h,(k,v)| h.merge(k => v ? v.strip : v)}.select{|_,v| v.length > 0 if v} => {:email=>"ab"} 1.9.3-p125 :032 > params => {:email=>" ab", :xyz=>" ", :opq=>nil}
Inject is a complex function that gets used to. I will try to explain this line step by step:
params.inject({}} says to create an empty hash to store our results.- | h, (k, v) | says to pass a new empty hash to the variable h, and also pass a key, a pair of values ββfrom our original hash params to k, v respectively.
Then it becomes more hairy. I will unpack the following command from the inside.
v ? v.strip : v v ? v.strip : v uses the ternary operator to return v.strip when v evaluates to true or v if v is false or nil
k => v ? v.strip : v k => v ? v.strip : v creates a new hash with the result
h.merge(k => v ? v.strip : v) merges our new hash into h, which started empty and then passes the result to the next iteration of the injection cycle.
in the next iteration of the loop, h will no longer be empty, and future results will continue to merge on it.
At this point, we shared the hash, and if we stayed here, the result would look like this:
1.9.3-p125 :032 > params => {:email=>" ab", :xyz=>" ", :opq=>nil} 1.9.3-p125 :033 > params.inject({}) {|h,(k,v)| h.merge(k => v ? v.strip : v)} => {:email=>"ab", :xyz=>"", :opq=>nil}
Now that the hash is removed, the select statement is direct. I use select here, not keep_if, because despite the absence !, Keep_if is a destructive method. See This Brew: http://news.ycombinator.com/item?id=2247352 . Since our injection instruction returns a hash, we can call it .select directly on it, although I do not propose making your lines of code so long in real practice.
1.9.3-p125 :034 > params => {:email=>" ab", :xyz=>" ", :opq=>nil} 1.9.3-p125 :035 > params.inject({}) {|h,(k,v)| h.merge(k => v ? v.strip : v)}.select{|_,v| v.length > 0 if v} => {:email=>"ab"}