Git Product home page Git Product logo

laravel-property-bag's People

Contributors

alexhupe avatar darkostanimirovic avatar kduma avatar luizvid avatar tzurbaev avatar zachleigh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-property-bag's Issues

Get users with a particular setting?

Hello,

This is a really awesome. Thanks for sharing. I'm wondering, is it possible to retrieve all users with a particular setting through the user Model? I figure the via setting model below could also work but maybe you have a way more efficient way?

PropertyBag::where('key', 'music_notifications')->where('value', true)->pluck('owner_id');

Have more control to choose when the properties should persist

Is there a way to add property bags as a new model is created ?
Currently it looks like the model must be existing first

$user = new User($data);
$user->save();
//Then add settings
$user->settings(['valid_date_or_birth',false]);

There is no way to add those settings prior to saving ?

$user = new User();
$user->settings(['valid_date_or_birth',false]);  
//The problem is that this will trigger a SQL query
//I am sure a workaround could be to set the settings first before adding any other data
// $user->save(); here then filling the data later on
$user->fill($data); // include operations that will be affected by the settings
$user->save();

One of the issues I have been running into is that I have settings in my model that affect some attributes and mutators. For example. If this valid_date_or_birth setting affect how a date format should change in either an accessor or a mutator. Because the user would not have an ID at the time this setting is stored, It will fail.
The problem is that as soon as the settings is set, it triggers a SQL query. However I would like to set those settings so that I can do extra computations (especially for models not currently saved)
and save those settings when its time to do so

class User extends Model{
    public function getDateAttribute(){
        //Perform operation based on the user settings
    }
    public function setDateAttribute(){
        //Perform operation based on the user settings
    }
}

Scoping to a value

@zachleigh - i know about withSetting.
It is a solid solution, but i do not think it scales very well
What would you say about this approach?

If the model's setting value is default, i do not expect to see a record in property bag.
If it is different from default, a record is in DB.

So:

/**
     * @param \Illuminate\Database\Eloquent\Builder $query
     * @param string $key
     * @param mixed $value
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeWhereHasSetting(Builder $query, $key, $value = null): Builder
    {
        // if the $value matches the default,
        // we need to return all models that DO NOT have the key in their property bag
        // otherwise, we need to scope DB for records that have it
        $default = $query->getModel()->defaultSetting($key);
        // matches precisely
        if ($default === $value) {
            return $query->whereDoesntHave(
                'propertyBag',
                fn(Builder $builder) => $builder->where('key', $key)
            );
        }
        // first we "cast" the value as array - same way Eloquent will
        $value = json_encode(Arr::wrap($value));
        // however, for lookup to work, we need to wrap the lookup string in double quotes
        return $query->whereHas(
            'propertyBag',
            fn(Builder $builder) => $builder->where('key', $key)->whereRaw('`value` = ?', json_encode($value))
        );
    }

Given value is not a registered allowed value for 0

hello,

this is my code :
App\Settings\UserSettings.php

    protected $registeredSettings = [

        'payment_method' => [
            'allowed' => ['bank', 'paypal','payoneer'],
            'default' => 'bank'
        ],

    ];

My controller

        $user = auth()->user();
        $request->validate([
            'payment_method' => 'in:bank,paypal,payoneer'
        ]);
        if($request->filled('payment_method')){
            if(!$user->settings()->keyIs('payment_method', $request->payment_method)){
                $user->settings(['payment_method',$request->payment_method]); //Problem is here
            }
        }

GET request URL : /settings/payments?payment_method=payoneer

And it works only with : paypal as a value
/settings/payments?payment_method=paypal

i have no idea whats going on

Update

1- "paypal" works because of the condition before saving the settings
2- i forgot to mention that i'm using laravel 5.7

error : Specified key was too long; max key length is 1000 bytes

i'm getting this error after running php artisan migrate

full error :

Illuminate\Database\QueryException  : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes (SQL: alter table 'property_bag' add unique 'property_bag_resource_type_resource_id_key_unique'('resource_type', 'resource_id', 'key'))

  at /vendor/laravel/framework/src/Illuminate/Database/Connection.php:664
    660|         // If an exception occurs when attempting to run a query, we'll format the error
    661|         // message to include the bindings with SQL, which will make this exception a
    662|         // lot more helpful to the developer instead of just the database's errors.
    663|         catch (Exception $e) {
  > 664|             throw new QueryException(
    665|                 $query, $this->prepareBindings($bindings), $e
    666|             );
    667|         }
    668|

  Exception trace:

  1   Doctrine\DBAL\Driver\PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes")
     /vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:119

  2   PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 1000 bytes")
      /vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:117

Performance

Hi!
Something should be wrong here ...
When I do something like this:

\App\models\User::withSetting("company", "name")

it performs this query:

select * from `property_bag` where `resource_type` = 'App\Models\User' and `property_bag`.`resource_id` in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)

and also all these queries:

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 1 and `property_bag`.`resource_id` is not null and `resource_id` = 1

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 2 and `property_bag`.`resource_id` is not null and `resource_id` = 2

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 3 and `property_bag`.`resource_id` is not null and `resource_id` = 3

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 4 and `property_bag`.`resource_id` is not null and `resource_id` = 4

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 5 and `property_bag`.`resource_id` is not null and `resource_id` = 5

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 6 and `property_bag`.`resource_id` is not null and `resource_id` = 6

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 7 and `property_bag`.`resource_id` is not null and `resource_id` = 7

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 8 and `property_bag`.`resource_id` is not null and `resource_id` = 8

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 9 and `property_bag`.`resource_id` is not null and `resource_id` = 9

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 10 and `property_bag`.`resource_id` is not null and `resource_id` = 10

select * from `property_bag` where `property_bag`.`resource_type` = 'App\Models\User' and `property_bag`.`resource_id` = 11 and `property_bag`.`resource_id` is not null and `resource_id` = 11

And this is in my development environment with 11 users ... I can't imagine if I have 3000 users and it has to do 3000 queries.

I think there's a missing "join" somewhere in the "withSetting" method.

migrate --provider option doesn't exist

php artisan migrate --provider="LaravelPropertyBag\ServiceProvider"

That --provider option doesn't exist in 5.3. I assume it can be changed to php artisan migrate?

How can we add Middleware?

Iโ€™m thinking about having some settings that are only available to premium users. Can we add middleware to UserSettings.php?

Set not creating

Edit nvm. Took me a while to understand set() doesn't create if it is the default value.

Although the json_encode is ugly if we're not using json in our db

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.