New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove ability to declare scopes in ActiveRecord, leave it to ActiveQuery #2016
Comments
@samdark Absollute agree! 👍 |
Vote for this too, but with some adjustments:
|
Makes a lot of sense, since we propose already separation for searching I vote for it! Edit:
Thats not actually a con since Yii2 already force users to adopt new standards |
|
just my +1 for this issue =) |
@samdark right, sorry for point 1. :) |
Finally, less than a year you have decided all the same it would be better :) But what about the opinion that in many cases will not have to make a second class UserQuery, but only one User? |
@slavcodev sure. You don't need |
You sure? You will have second class in 80% cases in real word app if you use behaviors, etc. |
And if you don't need IDE autocomplete. So, you need UserQuery. |
It was added mainly for practical reason because you may not want to take the trouble to write new query classes. I'm fine removing it if people don't like this convenience at all. |
How about to add a method to ActiveQuery: User::find()->scopeBy('active')->... which can call any query modifier callback. They are can be in any place -- custom query class, inline closure or static method. |
@tanakahisateru that's what we're trying to avoid: scope methods scattered all over the place. |
I totally agree to remove __call from ActiveQuery because it returns mixed and breaks IDE support for method chain. |
@samdark I'm afraid that beginners create fat controller having model knowledges instead of creating custom query. |
@tanakahisateru it will be clearly stated in the guide. |
Do I understand correctly? : It would be great, if all such a custom scopes could be maintained at one single place (e.g. shared class MyScopes extends ActiveQuery) and then if any model could read from it... But I am afraid this may not be possible. E.g. In some of my projects I have 20-30 models, out of which 30-40% use scopes. But even if not possible to place into a single class, I prone to give +1 vote due to clearer design. Performance impact is probably not that big issue even if sticking to 1.1 model. |
I don't see a major problem with that. I particularly like the fact that selection and manipulation are completely separated. |
Yes.
Only classes you have scopes in.
It is possible technically by returning the same query class from |
This would be really great!!! 👍 |
It should not be double. I will do if scope removed:
then
or
To add this |
@tanakahisateru |
Seems everyone is excited about this. I want to point out the following facts:
|
Oh if it would be supported by Gii, there are no problem! |
Only one proper way should be implemented - I dont see point to keep old (deprecated) approach from 1.1. |
What is the real consequence? User::query()->active()->olderThan(30); ? |
The consequence is that you lose the capability of defining scope methods in AR class, and you are forced to subclass ActiveQuery and put scope methods there (note that this is already supported currently). |
I like the idea of having a separate class to deal with scopes, but I think there should be a way to shorten the calling to eliminate the need to call User::find()->active()->all(); // currently
User::active()->all();
User::find()->olderThan(21)->all(); // currently
User::olderThan(21)->all();
User::find()->where(['email' => 'x@y.com'])->all(); // currently
User::where(['email' => 'x@y.com'])->all(); |
Well...putting scopes in the Query class will make code cleaner, so I see as a real benefit. |
@lucianobaraglia The current implementation already lets you do this. The question is whether we should always force this. |
Scopes without proper IDE support are not very usable, so i vote for this changes. There is no problem to have second class for model. |
Well, I guess this is the right thing 👍 , after all the name ActiveRecord is a representation of a record in a DB. So it makes no sense that this record should hold scopes used for searching other records of its kind :) it breaks the separation of concerns principle. |
Wouldn't this rule force coders to follow better coding approach by separating logic? When I first met Yii was impressed by its flexibility and freedom to do the same thing in many ways, but afterwards when we grow as a company, the same freedom lead us to see horrible coding pitfalls from employees. Restricting this freedom a little won't hurt anybody. |
@samdark then the Query class won't be used only for custom scopes but also for all finding methods...so chances are you will need the class at one time or another... |
Why you assume that? |
@creocoder because is the convention in this way of separating classes... Well, this is the way I worked with Symfony/Doctrine... |
Why drop a feature that may be used? When I only need one scope, why should I create separate class. Scopes in Query class are already supported so we should state arguments in another way. See #2016 (comment) The question is, why we should drop a feature as the requested feature is already supported. |
Btw: one of yii's strength is to keep things simple and easy. If you like the more ideological way of separating responsibilities that's fine and you are free to choose in this case. |
@cebe some cons of keeping both:
// ActiveRecord
public static function ageOf($query, $age)
{
$query->addWhere('age', 42);
}
// ActiveQuery
public function ageOf($age)
{
$this->addWhere('age', 42);
return $this;
} Confusing, isn't it? |
@cebe I really love what you mean about YII, that's why I ran away from other bloated frameworks... But in this point, I think it enforces a very good practice what will be very valuable when several developers with very different skill level will work in the same project in a long time span... |
I won't merge it for a couple of days at least. Need more opinions. |
okay, different signatures are a big argument. I'm quite convinced now. |
👍 for dropping the scopes in the ActiveRecord. Totally agree with @tonydspaniard in #2016 (comment) |
Here's possible trouble. Sometimes it's convenient to define 'global' scopes (that is, defined in parent class), like active(), visible() and so on. $query->andWhere(static::tableName() . '.is_disabled = 1'); If scopes are moving to AQ, there will be no access to tableName(), since it's an AR method. |
@o-rey maybe $this->andWhere($this->modelClass::tableName() . '.is_disabled = 1'); |
@slavcodev Yes, totally missed this one. Thx. |
Will following inheritance work?
If so, then it should be no problem to keep any scopes in a shared file. I see 3 reasons why users should be left with an option to keep scopes in a single file, if they want to:
Summing up - dropping Yii1 way about scopes within a model is OK but an option to keep scopes at one place in Yii2 would be very welcome. |
@lubosdz yes. It will work. Noone denies scopes in a single file. |
…s-in-ar Fixes #2016: removed ability to declare scopes in ActiveRecord leaving it to ActiveQuery
doesn't work for me with hasOne method. |
@nizsheanez that's a valid issue. Can you create a separate ticket? Thanks. |
sure |
… leaving it to ActiveQuery. Changed documentation accordingly.
Pros:
Cons:
Examples:
The text was updated successfully, but these errors were encountered: