belgoros
belgoros

Reputation: 3908

ActiveJDBC: use scope with dynamic parameters

The actual scope examples provide the use of hard-coded parameters passed to the query:

public class Employee extends Model {
    static {
        addScope("byDepartment", "department = 'marketing'");
    }
}

Is it possible to make that parameter dynamic and all the scope as follows:

public class Employee extends Model {
    static {
        addScope("byDepartment", "department = '?'");
    }
}

Example of use:

Employee.scope("byDepartment").where(....) <-- how to pass in a department value ?

Thank you.

Upvotes: 0

Views: 203

Answers (2)

Florent Curet
Florent Curet

Reputation: 1

I do not see anything wrong in making the parameter dynamic like in your Employee model:

public class Employee extends Model {
    static {
        addScope("byDepartment", "department = '?'");
    }
}

the issue is actually with

Employee.scope("byDepartment").where(....)

beside the scopeName, scope() does not provide any way for extra params for the scopeValue(s).

Instead you can call Employee.where(subquery, params)

where subquery would be your scopeQuery that you can access with ModelDelegate.getScopes().get(scopeName) and params would be your scopeValue.

Upvotes: 0

ipolevoy
ipolevoy

Reputation: 5518

Current implementation only works with hard-coded scopes. In general, having dynamic scopes is not any different than just having an additional parameter in a where() method, but will significantly complicate the implementation.

This question prompts for some philosophical discussion. Normally, you would be using a model as its own service. In other words, using a model like this from outside the model is not a preferred way:

List<Employee> employees = Employee.scope("byDepartment").where("start_date > ?", startDate);

It is best to wrap all access to the EMPLOYEES table into the Employee class like this:

public class Employee extends Model{
   public static List<Employee> getStartedByDepartment(Date started, String department){
          return Employee.scope(department).where("start_date > ?", started);
  } 
}

We code all JavaLite projects with this pattern, and do not allow ActiveJDBC API to bleed outside models (for the most part, lol).

As you can see, there is little that scopes will give you as the internal implementation of the model may or may not use scopes, you will get the same results. This coding pattern is much better becuase:

  1. You have static methods on Models you can test
  2. You have static methods that may have guard statements if (department = null) throw new IllegalArgumentException("blah...")
  3. You have static methods on Models that have good semantic names
  4. The implementation and access to your table is wrapped in one class, and not bled outside (controllers).
  5. Easy to do refactoring down the road.

However, if you use this approach, the value of scopes is near zero.

Needless to say, I do not use scopes in my work.

Upvotes: 1

Related Questions