Skip to content

Support ivars for all_* / *_cloud subquery blocks #24

@cupakromer

Description

@cupakromer

Issue

This is the first time we've started using this gem. One of the very first things we tried to do was define tags in a Rails controller (a view has the same issue) where we scoped the tags based on a scoped association using an instance variable.

For example, lets say there is a tagged Widget class which belongs to a Company. In this case we want all of the tags for a widget for a specific company. On the controller we have this code:

@company = Company.find(params[:id])
@tags = Widget.all_tags { where(company: @company) }

The current all_tags implementation is using instance_eval:

subquery_scope = subquery_scope.instance_eval(&block) if block

Since there is no @company on the class the scoped call "fails" returning an empty array [].

SELECT tag FROM (
    SELECT DISTINCT unnest(widgets.tags) as tag
      FROM "widgets"
      WHERE "widgets"."company_id" IS NULL
  ) subquery

Workaround

To work around this we need to create artificial local variables just for the block scope:

@company = Company.find(params[:id])
company = @company
@tags = Widget.all_tags { where(company: company) }

Which produces the correct result:

SELECT tag FROM (
    SELECT DISTINCT unnest(widgets.tags) as tag
      FROM "widgets"
      WHERE "widgets"."company_id" = 1
  ) subquery

Proposal

It would be great if we could avoid having to do this two-step by either having the scope yielded to the block or if the code could support block local variables:

# yield scope
Widget.all_tags { |scope| scope.where(company: company) }

# block local variables
Widget.all_tags(@company) { |company| scope.where(company: company) }

If the yield scope version would be a breaking change, maybe the unused options hash could be leveraged for a block local variable alternative; if there are no other plans for options.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions