Disable Global Scope on Query Builder

I can disable the global scope like this :

await Sender.queryWithOutScopes()
	.where("sender_id", sender_id)
	.with("user")
	.fetch();

But how to disable it also on relationship level which using .with() so it won’t follows the global scope?
Something like .withOutScopes()
Thanks in advance!

1 Like

Not sure if this is helpful or not… but I have a case where I’ve got a hierarchy of items, defined by an internal relationship… I wanted to be able to fetch the entire tree below a given point by default, but also avoid extra querying when not necessary…

This is (basically) my model:

class Thing extends Model {
  static boot () {
    super.boot()

    // If we haven't explicitly said _not_ to include children,
    // we will include them by default:
    this.addGlobalScope(builder => { 
      if (!builder.withoutChildren) builder.with('children')
    })
  }

  // Override default findOrFail method so that we can
  // Explicitly query _without_ including children
  static findOrFail (value, children = false) {
    if (children) {
      return this.query()
                 .where(this.primaryKey, value)
                 .firstOrFail()
    }
    return this.query()
               .without('children')
               .where(this.primaryKey, value)
               .firstOrFail()
  }

  // "Without" Scope that allows skipping inclusion of children,
  // Necessary since we otherwise _add by default_
  static scopeWithout (builder, relationship) {
    // force the relationship name to be camelcased.. "withoutChildren"
    builder['without' + relationship.toLowerCase().replace(/\b[a-z]/g, letter => letter.toUpperCase())] = true
  }


  // Relationships
  parent () {
    return this.belongsTo('App/Models/Thing', 'parent_id', 'id')
  }

  children() {
    return this.hasMany('App/Models/Thing', 'id', 'parent_id')
               .orderBy('name', 'asc')
  }
}

You could include a withoutUser in your scenario, and I think you might be able to put that onto the relationship itself… ie:

user() { 
  return this.without('user').belongsTo('App/Models/User')
}
1 Like

Hi , I think you misunderstand it. I just want to disable global scope on .with() level so it won’t follow the global scope also, something like .withOutScopes()

My Global Scope on Sender Model :

this.addGlobalScope(builder => {
			builder.setVisible(["sender_id", "sender_name", "sender_email"]);
			builder.with("user", builder => builder.select("id", "name"));
		});

When I do

await Sender.queryWithOutScopes()
	.where("sender_id", sender_id)
	.with("user", builder => {  
           builder.select(['address", "gender']);
        })
	.fetch();

The user object still returns id and name which means it still following the global scope even though I have used .queryWithOutScopes().

How about doing

with('user', (builder) => builder.ignoreScopes())
4 Likes

Nice, this is the one that I looking for. Thanks virk!

.with("user", builder => {
      builder.ignoreScopes();
      builder.select(["anything"]);
      builder.where(['anything']);
})

I can query what I want inside now