Skip to content
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

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 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.

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

No branches or pull requests

2 participants