Method: Sequel::Model::Associations::DatasetMethods#complex_expression_sql_append
- Defined in:
- lib/sequel/model/associations.rb
permalink #complex_expression_sql_append(sql, op, args) ⇒ Object
If the expression is in the form x = y
where y
is a Sequel::Model
instance, array of Sequel::Model
instances, or a Sequel::Model
dataset, assume x
is an association symbol and look up the association reflection via the dataset’s model. From there, return the appropriate SQL based on the type of association and the values of the foreign/primary keys of y
. For most association types, this is a simple transformation, but for many_to_many
associations this creates a subquery to the join table.
3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 |
# File 'lib/sequel/model/associations.rb', line 3061 def complex_expression_sql_append(sql, op, args) r = args[1] if (((op == :'=' || op == :'!=') && r.is_a?(Sequel::Model)) || (multiple = ((op == :IN || op == :'NOT IN') && ((is_ds = r.is_a?(Sequel::Dataset)) || (r.respond_to?(:all?) && r.all?{|x| x.is_a?(Sequel::Model)}))))) l = args[0] if ar = model.association_reflections[l] raise Error, "filtering by associations is not allowed for #{ar.inspect}" if ar[:allow_filtering_by] == false if multiple klass = ar.associated_class if is_ds if r.respond_to?(:model) unless r.model <= klass # A dataset for a different model class, could be a valid regular query return super end else # Not a model dataset, could be a valid regular query return super end else unless r.all?{|x| x.is_a?(klass)} raise Sequel::Error, "invalid association class for one object for association #{l.inspect} used in dataset filter for model #{model.inspect}, expected class #{klass.inspect}" end end elsif !r.is_a?(ar.associated_class) raise Sequel::Error, "invalid association class #{r.class.inspect} for association #{l.inspect} used in dataset filter for model #{model.inspect}, expected class #{ar.associated_class.inspect}" end if exp = association_filter_expression(op, ar, r) literal_append(sql, exp) else raise Sequel::Error, "invalid association type #{ar[:type].inspect} for association #{l.inspect} used in dataset filter for model #{model.inspect}" end elsif multiple && (is_ds || r.empty?) # Not a query designed for this support, could be a valid regular query super else raise Sequel::Error, "invalid association #{l.inspect} used in dataset filter for model #{model.inspect}" end else super end end |