Class: Squeel::DSL

Inherits:
Object
  • Object
show all
Defined in:
lib/squeel/dsl.rb

Overview

Interprets DSL blocks, generating various Squeel nodes as appropriate.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(caller_binding) ⇒ DSL (private)

This isn’t normally called directly, but via DSL.eval, which will pass the block’s binding to the new instance, for use with #my.

Parameters:

  • The (Binding)

    block’s binding.



49
50
51
# File 'lib/squeel/dsl.rb', line 49

def initialize(caller_binding)
  @caller = caller_binding.eval 'self'
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#node_nameNodes::Stub (private) #node_name(klass) ⇒ Nodes::Join (private) #node_name(first_arg, *other_args) ⇒ Nodes::Function (private)

Node generation inside DSL blocks.

Overloads:

  • #node_nameNodes::Stub

    Creates a Stub. Method calls chained from this Stub will determine what type of node we eventually end up with.

    Returns:

  • #node_name(klass) ⇒ Nodes::Join

    Creates a Join with a polymorphic class matching the given parameter

    Parameters:

    • klass (Class)

      The polymorphic class of the join node

    Returns:

    • (Nodes::Join)

      A join node with the name of the method and the given class

  • #node_name(first_arg, *other_args) ⇒ Nodes::Function

    Creates a Function with the given arguments becoming the function’s arguments

    Parameters:

    • first_arg

      The first argument

    • *other_args

      Optional additional arguments

    Returns:

    • (Nodes::Function)

      A function node for the given method name with the given arguments



107
108
109
110
111
112
113
114
115
116
117
# File 'lib/squeel/dsl.rb', line 107

def method_missing(method_id, *args)
  super if method_id == :to_ary

  if args.empty?
    Nodes::Stub.new method_id
  elsif (args.size == 1) && (Class === args[0])
    Nodes::Join.new(method_id, Arel::InnerJoin, args[0])
  else
    Nodes::Function.new method_id, args
  end
end

Class Method Details

.eval {|dsl| ... } ⇒ Object

Called from an adapter, not directly. Evaluates a block of Squeel DSL code.

Examples:

A DSL block that uses instance_eval

Post.where{title == 'Hello world!'}

A DSL block with access to methods from the closure

Post.where{|dsl| dsl.title == local_method(local_var)}

Yields:

  • (dsl)

    A block of Squeel DSL code, with an optional argument if access to closure methods is desired.

Returns:

  • The results of the interpreted DSL code.



27
28
29
30
31
32
33
# File 'lib/squeel/dsl.rb', line 27

def self.eval(&block)
  if block.arity > 0
    yield self.new(block.binding)
  else
    self.new(block.binding).instance_eval(&block)
  end
end

.exec(*args, &block) ⇒ Object

Called from an adapter, not directly. Executes a block of Squeel DSL code, possibly with arguments.

Returns:

  • The results of the executed DSL code.



39
40
41
# File 'lib/squeel/dsl.rb', line 39

def self.exec(*args, &block)
  self.new(block.binding).instance_exec(*args, &block)
end

Instance Method Details

#_(expr) ⇒ Nodes::Grouping (private)

Create a Squeel Grouping node. This allows you to set balanced pairs of parentheses around your SQL.

Parameters:

  • expr

    The expression to group

Returns:



79
80
81
# File 'lib/squeel/dsl.rb', line 79

def _(expr)
  Nodes::Grouping.new(expr)
end

#`(string) ⇒ Arel::Nodes::SqlLiteral (private)

Shorthand for creating Arel SqlLiteral nodes.

Parameters:

  • string (String)

    The string to convert to an SQL literal.

Returns:

  • (Arel::Nodes::SqlLiteral)

    The SQL literal.



70
71
72
# File 'lib/squeel/dsl.rb', line 70

def `(string)
  Nodes::Literal.new(string)
end

#my(&block) ⇒ Object (private)

If you really need to get at an instance variable or method inside a DSL block, this method will let you do it. It passes a block back to the DSL’s caller for instance_eval.

It’s also pretty evil, so I hope you enjoy using it while I’m burning in programmer hell.

Parameters:

  • &block

    A block to instance_eval against the DSL’s caller.

Returns:

  • The results of evaluating the block in the instance of the DSL’s caller.



62
63
64
# File 'lib/squeel/dsl.rb', line 62

def my(&block)
  @caller.instance_eval &block
end

#sift(name, *args) ⇒ Nodes::Sifter (private)

Create a Squeel Sifter node. This essentially substitutes the sifter block of the supplied name from the model.

Parameters:

Returns:



88
89
90
# File 'lib/squeel/dsl.rb', line 88

def sift(name, *args)
  Nodes::Sifter.new name.to_sym, args
end