Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Reference id is 0 #433

Open
nkhoangvu opened this issue Sep 24, 2024 · 3 comments
Open

Reference id is 0 #433

nkhoangvu opened this issue Sep 24, 2024 · 3 comments
Labels

Comments

@nkhoangvu
Copy link

nkhoangvu commented Sep 24, 2024

I don't know this is a bug or I did not find the properly way to handle the package. If the id of Post is input manually by form:

class Job extends Model implements TranslatableContract
{
    use SoftDeletes, Translatable;

    public $timestamps = true;
    public $translatedAttributes = ['title', 'content'];
    public $translationForeignKey = 'post_id';
    protected $table = 'posts';  
    
    protected $primaryKey = 'id';
    protected $keyType = 'string';
    protected $dates = ['deleted_at'];
    protected $fillable = [
        'id',
        'title',
        'category_id',
        'published',
	'user_id',
    ];
}

then:

$input = $request->validated(); 
$post = Post::create($input);

The translation is excuted automatically in the same way with $post = Post::update($input) but the value of post_id cannot get properly, it always is 0, Although at that moment the new record $post was already created in DB.
Although I tried:

$input['translation'] = [
            session('locale') => [
                'title' => $request->input('title'),
                'content' => $request->input('content')
            ],
        ];
$post = Post::create($input);

But no success.

How should I overcome this situation. Thank you.

Note: Everything works properly if the id is auto increment.

Versions (please complete the following information)

  • PHP: 8.1
  • Database: MySQl 5.7
  • Laravel: 11
  • Package: Astrotomic/laravel-translatable
@nkhoangvu nkhoangvu added the bug label Sep 24, 2024
@Oleksandr-Moik
Copy link
Contributor

Hi, @nkhoangvu!

For your problem, I suggest changing the array format for creating a post or changing the configuration to use a wrapper for transaltions.

If you need more information, see below.


By default, if you need to create a post with translations, you must pass an array with one of the next formats (see more on usage/forms:

1 - using array format

$post->fill([
  'en' => [
    'title' => 'My first edited post',
  ],
  'de' => [
    'title' => 'Mein erster bearbeiteter Beitrag',
  ],
]);

Example from test - https://github.com/Astrotomic/laravel-translatable/blob/main/tests/TranslatableTest.php#L210-L225

2 - using plain (with colon) format

$post->fill([
  'title:en' => 'My first edited post',
  'title:de' => 'Mein erster bearbeiteter Beitrag',
]);

Example from test - https://github.com/Astrotomic/laravel-translatable/blob/main/tests/TranslatableTest.php#L112-L123


From the latest versions of a package, you can use a new format, with a wrapper for translations (see in docs)

$data = [
  'author' => 'Gummibeer',
  'translations' => [
      'en' => ['title' => 'My first post'],
      'fr' => ['title' => 'Mon premier post'],
  ],
];
$post = Post::create($data);

Example from test - https://github.com/Astrotomic/laravel-translatable/blob/main/tests/TranslatableTest.php#L228-L247

@nkhoangvu
Copy link
Author

nkhoangvu commented Sep 27, 2024

None of above method can help.
I also tried as below but the same failed results:

$input = $request->validated(); 
$published = $request->boolean('published');
$input['published'] = $published ? 1 : 0;
$input['translation'] = [
       session('locale') => ['title' => $request->input('title')]
 ];
$post = Post::create($input);    

and this:

$data = new Post();
$data->fill([
            'id' => $input['id'],
            'category_id' => $input['category_id'],
            'company_id' => $input['company_id'],            
            'published' => $input['published'],
            'user_id' => $input['user_id'],
            session('locale') => ['title' => $input['title'], 'content' => $input['content']],
]);
$data->save();

Note that the post_id is varchar(8) and not auto-increment and I only need to update only one language at a time depend on session language session('locale').
Everything is normal with update. But when create a new post, the post_id is always 0 which causes error because the relationship between posts & post_translation table (SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails)

Below is my Post model:

<?php
namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Astrotomic\Translatable\Contracts\Translatable as TranslatableContract;
use Astrotomic\Translatable\Translatable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Facades\Notification;
use App\Notifications\PostAction;
use RalphJSmit\Laravel\SEO\Support\HasSEO;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
use Spatie\Sluggable\HasSlug;
use Spatie\Sluggable\SlugOptions;
use Spatie\Tags\HasTags;

class Post extends Model implements TranslatableContract
{
    use HasSlug, HasTags, LogsActivity;
    use HasSEO, SoftDeletes, Translatable, Notifiable;

    public $timestamps = true;
    public $translatedAttributes = ['title', 'content'];
    protected $table = 'posts';  
    
    protected $primaryKey = 'id';
    protected $keyType = 'string';
    protected $dates = ['deleted_at'];
    protected $fillable = [
        'id',
        'title',
        'category_id',
        'published',
		'user_id',
    ];

   
    protected static function sendNotifications($job, $action)
    {
        $recipients = User::whereHasRole('super-admin')->get();
        Notification::send($recipients, new JobAction($job, $action));
    }

    public function getRouteKeyName()
    {
        return 'slug';
    }

    public function scopePublished($query)
    {
        return $query->where('published', true);
    }    

    public function getSlugOptions() : SlugOptions
    {
        return SlugOptions::create()
            ->generateSlugsFrom('title')
            ->saveSlugsTo('slug')
            ->slugsShouldBeNoLongerThan(254);
    }
    
    /* Activity Log */
    public function getDescriptionForEvent(string $eventName) : string {
        return "A job have been {$eventName}";
    }
    
    public function getActivitylogOptions(): LogOptions
    {
        return LogOptions::defaults()
            ->useLogName('article')
            ->logOnly(['title', 'category_id', 'date', 'published', 'user_id'])
            ->logOnlyDirty();
    }
    
    public function category()
    {
        return $this->belongsTo(Category::class, 'category_id', 'id');
    }

    public function author()
    {
        return $this->belongsTo(User::class, 'user_id', 'id');
    }
    
    protected static function boot()
    {
        parent::boot();

        static::created(function ($post) {
            self::sendNotifications($post, 'created');
        });

        static::updated(function ($post) {
            self::sendNotifications($post, 'updated');
        });
    }   
}

@Oleksandr-Moik
Copy link
Contributor

Ok, I will check it later.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
Development

No branches or pull requests

2 participants