Giter Club home page Giter Club logo

laravel-merged-relations's People

Contributors

chrishardie avatar staudenmeir 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

laravel-merged-relations's Issues

Intermediate Table with Model View

Hi !

I'm using both of your (amazing) packages : staudenmeir/eloquent-has-many-deep and staudenmeir/laravel-merged-relations.

And I have an issue when I want to use them together. Let me explain that.

I have a User with a deep relationship, with two morphedToMany :

  • User -> BelongsToMany -> Flux -> MorphedByMany -> RssContent.
  • User -> BelongsToMany -> Flux -> MorphedByMany -> TwitterContent
    This two are working very well, included with the withIntermediate().

I need to get both of this contents (Rss and Twitter) in the same call. So, here, I use the laravel-merged-relations, with a view. Here is the code of my model :

class User extends Authenticatable
{
    use \Staudenmeir\EloquentHasManyDeep\HasRelationships;

    public function rss_contents()
    {
        return $this->hasManyDeep(
            RssContent::class,
            [ 'flux_user', Flux::class, 'flux_contents'],
            [ null, null, 'flux_id', 'id' ],
            [ null, null, 'id', ['flux_content_type', 'flux_content_id']]
        )->withIntermediate(Flux::class);
    }

    public function twitter_contents()
    {
        return $this->hasManyDeep(
            TwitterContent::class,
            [ 'flux_user', Flux::class, 'flux_contents'],
            [ null, null, 'flux_id', 'id' ],
            [ null, null, 'id', ['flux_content_type', 'flux_content_id']]
        )->withIntermediate(Flux::class);
    }

    use \Staudenmeir\LaravelMergedRelations\Eloquent\HasMergedRelationships;

    public function all_contents()
    {
        return $this->mergedRelation('all_user_contents');
    }

My migration looks like this:

class CreateUserContentsMergeView extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::createMergeView('all_user_contents', [(new User)->rss_contents(), (new User)->twitter_contents()
        ]);
    }
}

All of this is working very well.

BUT... when I call the all_contents method, I can't access the intermediate Flux::class. I think this is normal because it's not in my view.. but I don't know how to have it.

Do you you have an idea how?

Thanks a lot for your help!

"Invalid authorization specification" on restored DB

After dropping my dev database and restoring the live database containing a view created by this plugin, i get the following error:

SQLSTATE[28000]: Invalid authorization specification: 1045 Access denied for user 'db'@'%' (using password: YES)

The other tables working like normal.
If I delete the view and re-run the migration it works again.

Is this a known problem?

[MergedRelationWithModel] - Merge 3 relationships is not working

Hello, i can't make the mergedRelationWithModel work with my structure. Can you take a look of what i'm doing wrong?

Schema::createOrReplaceMergeView('participants', [(new Blog)->user(), (new Blog)->creator(), (new Blog)->commenters()]);

Results in:

CREATE 
    ALGORITHM = UNDEFINED 
    DEFINER = `username`@`ip` 
    SQL SECURITY DEFINER
VIEW `database`.`participants` AS
    SELECT 
        `database`.`users`.`username` AS `username`,
        `database`.`users`.`id` AS `laravel_foreign_key`,
        'App\Models\User' AS `laravel_model`,
        '' AS `laravel_placeholders`,
        '' AS `laravel_with`
    FROM
        `database`.`users`
    WHERE
        (`database`.`users`.`deleted_at` IS NULL) 
    UNION ALL SELECT 
        `database`.`users`.`username` AS `username`,
        `database`.`users`.`id` AS `laravel_foreign_key`,
        'App\Models\User' AS `laravel_model`,
        '' AS `laravel_placeholders`,
        '' AS `laravel_with`
    FROM
        `database`.`users`
    WHERE
        (`database`.`users`.`deleted_at` IS NULL) 
    UNION ALL SELECT DISTINCT
        `database`.`users`.`username` AS `username`,
        `database`.`blog_comments`.`blog_id` AS `laravel_foreign_key`,
        'App\Models\User' AS `laravel_model`,
        '' AS `laravel_placeholders`,
        '' AS `laravel_with`
    FROM
        (`database`.`users`
        JOIN `database`.`blog_comments` ON ((`database`.`users`.`id` = `database`.`blog_comments`.`user_id`)))
    WHERE
        (`database`.`users`.`deleted_at` IS NULL)

Blog Model

class Blog extends Model
{
    use \Staudenmeir\LaravelMergedRelations\Eloquent\HasMergedRelationships;

    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function creator(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function commenters(): BelongsToMany
    {
        return $this->belongsToMany(User::class, BlogComment::class)->distinct();
    }

    /**
     * Get participants in the blog.
     *
     * @todo: We should get the users who comments + creator + user
     * 
     * @return MergedRelation
     */
    public function participants(): MergedRelation
    {
        return $this->mergedRelationWithModel(User::class, 'participants');
    }
}

Expected result

$blog->participants returns the user + creator + commenters

Result

$blog->participants is just returning the commenters

$blog->participants raw sql query results in:

f3a002e2-5ecb-4205-aefd-cfb2ecc0112e is the primary key for the Blog Model

select * from `participants` where `participants`.`laravel_foreign_key` = 'f3a002e2-5ecb-4205-aefd-cfb2ecc0112e' and `participants`.`laravel_foreign_key` is not null

If you need more information, please feel free to tell

Thank you,
Mário

Seeding MergedRelationship with Model Factory

The User Model has a merged relationship called connections:

  public function connections(): MergedRelation
  {
      return $this->mergedRelationWithModel(User::class, 'connections_view');
  }

which is connected with the following connections_view:

  public function up()
  {
      Schema::createMergeView(
          'connections_view',
          [(new User())->acceptedConnectionsFrom(), (new User())->acceptedConnectionsTo()]
      );
  }

It merges together the connections between two users, where a user can either be the sender or the receiver of a connection request. That is why we need two relationships for it. If you do not understand what I mean, check out https://blog.codecourse.com/setting-up-laravel-friendship-relations

In my seeder or in my tests I would now like to create records for the mergedRelation like so:

  public function test_try_to_seed_user_with_friends() 
  {
      $user = User::factory()
                  ->hasConnections(10)
                  ->create();
  }

Unfortunately this throws the following error:

  SQLSTATE[HY000]: General error: 1 table users has no column named laravel_foreign_key (SQL: insert into "users" ("name", "email", "email_verified_at", "password", "remember_token", "userable_id", "userable_type", "laravel_foreign_key", "updated_at", "created_at") values (Kareem Jast I, [email protected], 2022-11-04 14:22:07, $2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi, CqbC0RCmTK, 2, App\Models\Site, 1, 2022-11-04 14:22:07, 2022-11-04 14:22:07))

Is it possible to fix it?

Enforce morph map not applied

Hey,

I am using this package with enforcing a morph map like this

Relation::enforceMorphMap([
            'dropbox' => Dropbox::class,
            'ftp' => Ftp::class,
            's3' => S3::class,
            'user' => User::class,
        ]);

In the created view I see the column laravel_model with the full path/namespace.

Shouldn't this be decoupled when using a morph map?

Failed to create merge view

I have error Error: Call to undefined method Staudenmeir\LaravelMergedRelations\Facades\Schema::createMergeView() in file /public_html/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php on line 353.

Question on writability of the relation

Hi @staudenmeir.
I stumbled onto your package and I have to say it's really great work.

Even if it's not documented I tried a $model->all_related->save($relatedModelInstance) but it doesn't work.
I guess this is not supported yet but it may be my fault... any clue?

Thanks for taking the time.

Incompatible with staudenmeir/eloquent-has-many-deep?

Hello, I am already using staudenmeir/eloquent-has-many-deep relationships and wanted to use this package as well. However, I noticed these seem to be incompatible, am I correct?

staudenmeir/laravel-merged-relations: v1.5.2
staudenmeir/eloquent-has-many-deep: v1.17.1
Laravel: 9.46

When I'm trying to create a merged view with a relation which is defined using hasManyDeepFromRelations(), it uses the wrong 'base model'

In model "A":

public function c()
{
	return $this->hasManyDeepFromRelations($this->b(), (new B)->c());
}

Creating schema:

Schema::createMergeViewWithoutDuplicates(
        'all_cs',
        [(new A)->c()]
);

Results in:

CREATE OR REPLACE
ALGORITHM = UNDEFINED VIEW `all_cs` AS
select
    `cs`.`id` AS `id`,
    `cs`.`name` AS `name`,
    `cs`.`created_at` AS `created_at`,
    `cs`.`updated_at` AS `updated_at`,
    `bs`.`id` AS `laravel_foreign_key`,
    'App\\Models\\C' AS `laravel_model`,
    '' AS `laravel_placeholders`,
    '' AS `laravel_with`
from
...

Expected result:

I was expecting it would do
`as`.`id` AS `laravel_foreign_key`
instead of
`bs`.`id` AS `laravel_foreign_key`

It does create the correct query to query using a B model. It seems to skip the first level (from what I would expect, at least).

Migration error

Hello,

So am getting this error when I do php artisan migrate, which says:

**Illuminate\Database\QueryException

SQLSTATE[42883]: Undefined function: 7 ERROR: operator does not exist: boolean = integer at character 499**

Am just doing how the view example shows, here's my code:

    use Staudenmeir\LaravelMergedRelations\Facades\Schema;

    public function up()
    {
        Schema::createMergeView(
            'friends_view',
            [( new User())->acceptedFriendsOf(), ( new User())->acceptedFriendsOfMine()]
        );
    }

Adding pivot columns to the generated views

Is it possible to add pivot columns to the generated view?

I have a users table and a pivot table for friends which contains the user_id, friend_id and accepted_at.

Is it possible to get the accepted_at in the generated view?

Error: Class name must be a valid object or a string

I was so happy to find this package today! Thank you for creating it!!

It is mostly working fine for me, but I noticed that when I add a ->select('column') query modifier to the view query, I get some warnings and errors:

<warning>PHP Warning:  Undefined property: stdClass::$laravel_model in vendor/staudenmeir/laravel-merged-relations/src/Eloquent/Builder.php on line 23</warning>
<warning>PHP Warning:  Undefined property: stdClass::$laravel_placeholders in vendor/staudenmeir/laravel-merged-relations/src/Eloquent/Builder.php on line 27</warning>
PHP Error:  Class name must be a valid object or a string in vendor/staudenmeir/laravel-merged-relations/src/Eloquent/Builder.php on line 35

Here's the query I'm running:

$source->newsItems()->select('external_id')->get();

and the SQL it is generating:

select `external_id` from `source_all_newsitems` where `source_all_newsitems`.`laravel_foreign_key` = ? and `source_all_newsitems`.`laravel_foreign_key` is not null"

Here's the Source model setup:

    public function feedNewsItems()
    {
        return $this->hasManyThrough(NewsItem::class, Feed::class);
    }

    public function directNewsItems()
    {
        return $this->hasMany(NewsItem::class);
    }

    public function newsItems()
    {
        return $this->mergedRelationWithModel(NewsItem::class, 'source_all_newsitems');
    }

and the migration:

        Schema::createMergeView('source_all_newsitems', [
            (new \App\Models\Source())->feedNewsItems(),
            (new \App\Models\Source())->directNewsItems()
        ]);

Note that if I run the query without the select() modifier, it works fine. I see the limitation disclaimer about not being able to specify columns in the view creation, but it looks like it should be possible to specify columns in the query of the view, unless I'm missing something.

Issue after upgrading with missing method

After upgrading this package to the new release and running my test suite which uses sqlite with an in memory database I'm getting an error with it not finding Call to undefined method Staudenmeir\LaravelMigrationViews\Schema\Builders\SQLiteBuilder::createOrReplaceMergeView() however if I look inside the vendor folder and find the SQLiteBuilder file I do find the method inside of the CreatesMergeViews trait.

I did not get this error when I ran my tests pior to the upgrading this package and upgrading Laravel to 9.

<?php

use App\Models\Group;
use Illuminate\Database\Migrations\Migration;
use Staudenmeir\LaravelMergedRelations\Facades\Schema;

class CreateAllGroupMembersView extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::createOrReplaceMergeView(
            'all_group_members',
            [(new Group)->teachers(), (new Group)->students()]
        );
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropView('all_group_members');
    }
}

"Base table or view already exists" when running test suite

I'm getting a phpunit test suite set up for a project where I'm using this package, and immediately started encountering "Base table or view already exists" errors for the created view on n>=2 runs of the tests. My best guess is that something about the existence of a view is not expected in the way Laravel handles creating and cleaning up the test database structure. But it's also possible/likely I've configured something incorrectly.

Do you have any guidance on how to address this? For now I'm adding a Schema::dropViewIfExists() call to the migration's up() method as a workaround. Thank you.

createMergeViewWithoutDuplicates fails when a json column exists

DB: PostgreSQL 13.6
Laravel: 9.38.0

When trying to create a merged view without duplicates on a table with json columns an error is thrown. If duplicates are allowed it works fine.

Schema::createMergeViewWithoutDuplicates(
    'business_all_gatherings',
    [(new \App\Models\Business())->productGatherings(), (new \App\Models\Business())->activityGatherings()]
);

Output:

SQLSTATE[42883]: Undefined function: 7 ERROR:  could not identify an equality operator for type json...

Column already exists error

I get an error when migrating

error:

 SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name

migration:

Schema::createMergeViewWithoutDuplicates(
            'movie_recommended_view',
            [(new Movie())->recommended(), (new Movie)->recommendedFor()]
        );

relationships:

    public function recommended(): BelongsToMany
    {
        return $this->belongsToMany(static::class, 'movie_recommended', 'movie_id', 'recommended_id' ,'tmdb_id' , 'tmdb_id');
    }

    public function recommendedFor(): BelongsToMany
    {
        return $this->belongsToMany(static::class, 'movie_recommended', 'recommended_id', 'movie_id' ,'tmdb_id' , 'tmdb_id');
    }

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.