On 07.12.2012 21:02, rosenfeld (Rodrigo Rosenfeld Rosas) wrote:
>
> Issue #4085 has been updated by rosenfeld (Rodrigo Rosenfeld Rosas).
>
>
> Aaron, I see your point but often my queries are much more complex than a single mention to some column. So if I have to repeat an unrepresentable column multiple times I'd prefer the block approach.
>
> When I mentioned the DSL issues I did it from my previous experience with Grails. In Grails you can bind the params arguments as the controller's method's arguments. So, consider this:
>
> class SomeController {
>    def someAction(String name) {
>      MyDomainClass.find { name == name} // WTF?! I want to compare the "name" column to the value of the "name" param
>    }
> }
>
> I know this isn't possible in Ruby (the params binding feature). But what if you want to compare "name" column to the result of a call to the "name" local (or inherited) method?

Named parameters? Depends. If you can splat them I would simply suggest 
moving the thing to a different method which won't suffer from scoping 
issues. But really, that's a Groovy-issue in so far that it gives local 
variable names (method argument names essentially are local vars) a 
non-local significance which robs you of the freedom of renaming them as 
you desire without breaking code.

But there are solutions. Remember that it's instance_eval'd:

     MyDomainClass.find { self.name == name}

Alternatively you can teach the DSL some smartness and switch between 
call and instance_eval based on arity:

     MyDomainClass.find {|d| d.name == name}


There are many ways to solve this problem without polluting any external 
object.

>  So if I have to repeat an unrepresentable column multiple times I'd prefer the block approach.

Block approach is a bad name for this, since both approaches are using 
blocks ;) Anyway, this problem can be solved too:

    Foo.dsl do
      col = __send__("illegal_name")
      col.eq(coalesce(id,title)) | col.like("%bar%")
    end

In fact, squeel provides an even more elegant solution. Since column 
names often are escaped with the ` character and that's a valid method 
name in ruby it provides literals that way:

    MyModel.where{other_table.`literal_name` == "bar"}


You're really bringing up edge cases here for which there are multiple 
solutions. There is no necessity to monkey-patch Symbol only to build 
some DSLs, really.