Eloquent Intermediate Tabel with None Standard ID Column - laravel

While creating my database according to the eloquent standard, I ran into the problem that my table_name and id column name combined would be longer as 64 characters.
very_long_table_name.very_long_column_name_id
So I used a shorter column name as the foreign key in my Intermediate Table.
Migration file:
$table->unsignedBigInteger('short_id');
$table->foreign('short_id')->references('id')->on('very_long_table_name');
That worked fine, yet now I would like to insert a connection
Seeder.php:
$x->very_long_table_name()->attach($other_table_name->id);
I get the error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'very_long_column_name_id' in 'field list' (SQL: insert into very_long_table_name (just_an_id, very_long_column_name_id) values (1, 1))
What I would want is that it would use the column short_id instead of very_long_column_name_id to insert this, is there any cool way to fix this? or do I need to insert and query the connection manually if I keep the long names?

Like #Tim points out in the comments this needs to be done in the Model VeryLongTableName.php where you define the relationship:
public function very_long_table_name() {
return $this->belongsToMany(Model::class, 'very_long_table_name', 'local_id', 'short_id');
}

Related

How to access to user data through intermediate table (hasOneThrough / hasManyThrough)

For a job posting application, I have three tables, which shortly are defined as:
applications:
id as primary key
job_offer_uuid as external key
job_offers:
uuid as primary key
user_id as external key
users:
Just laravel normal users table with id as primary key
Because I need to notify job_offer owner (a member of User model) any time that an application is registered, I'm trying to create a hasOneThrough or hasManyThrough relationship from applications to users, but without success for the moment.
For clarification:
User model only hosts users that publish job offers, and any user can publish many job offers. There is not applicants in users table
Based on my understanding of eloquent documentation (https://laravel.com/docs/8.x/eloquent-relationships#has-one-through), my actual code in Application model is:
public function publisher()
{
return $this->hasOneThrough(User::class, JobOffer::class, 'job_offer_uuid', 'user_id');
}
But it fires an SQL error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'job_offers.job_offer_uuid' in 'field list' (SQL: select `users`.*, `job_offers`.`job_offer_uuid` as `laravel_through_key` from `users` inner join `job_offers` on `job_offers`.`id` = `users`.`user_id` where `job_offers`.`job_offer_uuid` in (1)
using hasManyThrough instead, I got an identical error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'job_offers.job_offer_uuid' in 'field list' (SQL: select `users`.*, `job_offers`.`job_offer_uuid` as `laravel_through_key` from `users` inner join `job_offers` on `job_offers`.`id` = `users`.`user_id` where `job_offers`.`job_offer_uuid` in (1))
I can get accurate results using pure SQL with a sentence like this:
select applications.id, applications.job_offer_uuid, job_offers.uuid, job_offers.user_id, users.id, users.name, users.email from `applications` inner join job_offers on `applications`.`job_offer_uuid` = `job_offers`.`uuid` join users on job_offers.user_id = users.id where `applications`.id = 1
Any video or tutorial that I found related to this point are using the final table with a foreign key to the intermediate table, and thats means my User model should have a foreign job_offer_id key, but that make no sense to me.
Any clarification should be truly appreciate. Regards!
You are doing it wrong. You have to define relationship in User Model as follow:
public function publisher()
{
return $this->hasOneThrough(
Application::class,
JobOffer::class,
'user_id', // Foreign key on job_offers table
'job_offer_uuid', // Foreign key on applications table
'id', // Local key on user table
'uuid' // Local key on job_offer table
);
}

Unknown Column when using where clause in set relation n-n

when I use set relation n-n with where clause like this
$crud->set_relation_n_n('actors', 'film_actor', 'actor', 'film_id', 'actor_id', 'fullname', null, $this->db->like('actor.actor_name','Katja' , 'both');
this is not working (Unknown column 'actor.actor_name' in 'where clause') but when I put in the where clause column from the first table it would work. like this
$crud->set_relation_n_n('actors', 'film_actor', 'actor', 'film_id', 'actor_id', 'fullname', null, $this->db->like('film.film_name','taken' , 'both');
So I cannot access the fields from the selected table!!
I need to search the name of the actors, Could someone please help
Is there a shorter way as using the actor's table as the main table, and then filter it with $crud->where()?
thanks

Laravel Find Not working with custom primary key

I am stuck with a situation where i coudn't update my records using Eloquent in Laravel 5.5 using custom primary key.
Here is what i tried :-
In my Model.php i have,
protected $primarykey = 'custom_primary_key';
my migrations looks like :-
$table->increments('custom_primary_key');
in my controller,i have :-
Model::find(custom_primary_key);
but when i tries to find a record using find() in my controller, it gives
Column not found: 1054 Unknown column 'table.id' in 'where clause' (SQL: select * from `table` where `table`.`id` = 1 and `table`.`deleted_at` is null limit 1)"
table also contains a column with custom primary key and there is no column named id.
It doesnt recognize the cutom primary key. Where can i be missing something ?
Set $primarykey into $primaryKey. Check the documentation from Laravel here:
https://laravel.com/docs/5.6/eloquent#eloquent-model-conventions

sql 42S22 error in Laravel (choosing a column I didn't mention)

I am doing a basic project in Laravel, when trying to delete an entry, it generates this error:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'id' in 'where clause' (SQL: select * from `employees` where `id` = 6 limit 1)
and it is true I don't have a column named 'id', instead I have employee_id, but why is it choosing id instead of employee_id?
Please explain from where did it bring this id column?
In your Employee model (Employee.php), add
protected $primaryKey = 'employee_id';
This will tell Laravel to use employee_id as the primary key for Empolyee objects.

How alter column type with using toUInt32OrZero function in clickhouse?

I have String column in clickhouse table.
I try alter table with modify type to UInt32:
ALTER TABLE main.abonents
MODIFY COLUMN
device_type UInt32 DEFAULT 0
but have error:
Received exception from server:
Code: 6. DB::Exception: Received from 5.200.55.122:9000. DB::Exception: Cannot parse string 'mo' as UInt32: syntax error at begin of string. Note: there are toUInt32OrZero function, which returns zero instead of throwing exception..
It's clear, clickhouse use toUint32 function on string like 'mobile' and throw exception. And its advice to use function toUInt32OrZero to convert type.
How can i use toUInt32OrZero function with ALTER TABLE??
There's no such way (as far as I know).
You can achieve it with a second table. Let's create one:
CREATE TABLE main.abonents_new AS main.abonents;
Then we have to alter column in that new table.
This table has no data yet, so it won't raise exceptions:
ALTER TABLE main.abonents_new MODIFY COLUMN device_type UInt32 DEFAULT 0;
Then, make sure no new data is written to main.abonents. We'd like to keep everything in place when we'll transfer the data to the new table.
Insert the data using INSERT INTO SELECT query. Make sure to list all the fields with the same order; wrap device_type to the converter function (toUInt32OrZero) :
INSERT INTO main.abonents_new SELECT field1, field2, ..., toUInt32OrZero(device_type) AS device_type, ..., fieldN FROM main.abonents;
Then, make sure that everything's alright (that rows count is the same, device_type was converted as intended, etc), then rename the tables:
RENAME TABLE main.abonents TO main.abonents_old;
RENAME TABLE main.abonents_new TO main.abonents;
(or, you may DROP the older table instead; although I'd keep the old data to be able to restore if things'd go south)

Resources