Replace $request->all() with only non empty form fields - laravel

is it possible to replace $request->all() in the below line with only fields that are not empty in submitted form.
$product = Product::create($request->all());
when some form fields are empty, the query generated is something like
insert into `products` (`name`, `companyname`, `ip`, `host`, `status`, `language`, `updated_at`, `created_at`) values (efesar, ewrewrewre, , , , , 2018-04-18 10:29:11, 2018-04-18 10:29:11))
And that's returning error.

This would get you only the fields with values:
$data = collect($request->all())->filter()->toArray();
$product = Product::create($data);
But you should get from the request only the fields which are appropriate for your Product model or better yet, add validation for them. Depending on what you need, you might have to change some your table fields to be nullable to be able to save empty fields.

Its not a problem to submit null fields. Just make them nullable in migration file:
$table->string('ip')->nullable();
$table->string('host')->nullable();
$table->string('status')->nullable();
$table->string('language')->nullable();

Related

How to get specific columns from relation table in laravel?

I am trying to fetch soecific columns data from relational table but it is giving me null
$allConsignments = Consignment::query();
$allConsignments->select(['id','customer_reference'])->with('customers:name,id')->orderBy('id', 'desc')->limit(5000)->get();
When I don't use select() then it gives correct data .
like this
$allConsignments = Consignment::query();
$allConsignments->with('customers:name,id')->orderBy('id', 'desc')->limit(5000)->get()
it is working but I also need specific columns from Consignment Table. what could be the reason?
You can also do like this.
$allConsignments = Consignment::query();
$allConsignments::with('customers:name,id')->orderBy('id', 'desc')->limit(5000)->get(['id','customer_reference']);
Actually, I also need to select the foreign key column from the table on which relationship is based. for example in my case I have customer_id in consignment table so it should be like that
$allConsignments = Consignment::query();
$allConsignments->select('id','customer_reference','customer_id')->with('customers:name,id')->orderBy('id', 'desc')->limit(5000)->get();
I need to select customer_id as well

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

How To Delete Multiple Rows from Table Using Laravel Eloquent?

I want to delete multiple rows from my post_tags table where post_id is given .
table structure post_tags is : post_id , tag_id , created_at , updated_at
I am able to do this operation with DB query builder , but i want to
delete multiple rows with single elequent command without using forloop
I don't know how to do this ?
You should try this:
$post_id = [1,2,3];
DB::table('post_tags')
->whereIn('id',$post_id)
->delete();
You can pass Model::destroy($ids) an array. Alternatively, loop the records you want to delete and call delete on each: $model->postTags->each->delete().

Updating a Magento product attribute's database field type after creation

The scenario: You've created a product attribute programmatically using a database migration. Several months later you'd like to change that attribute from a VARCHAR to a TEXT field type.
How do you change the field type of an EAV attribute after creation while preserving the data?
My gut feeling is that this isn't supported directly through Magento's setup classes, due to the myriad of tables that would need to be touched, records that would need to be updated and content that would need to be copied from table to table.
I'm not going to pretend this is the prettiest solution around, and I'm doubtful it's database agnostic, but here's my solution:
<?php
/** #var $this Mage_Eav_Model_Entity_Setup */
$this->startSetup();
$attribute_id = $this->getAttribute(
Mage_Catalog_Model_Product::ENTITY,
'your_attribute_code',
'attribute_id'
);;
if (!is_numeric($attribute_id)) {
Mage::throwException("Couldn't run migration: Unable to find attribute id");
}
/** #var Varien_Db_Adapter_Pdo_Mysql $connection */
$connection = $this->getConnection();
$connection->beginTransaction();
/**
* Copy the data from the VARCHAR table to the TEXT table.
*/
$connection->query("
INSERT INTO catalog_product_entity_text
(entity_type_id, attribute_id, store_id, entity_id, value)
SELECT
entity_type_id, attribute_id, store_id, entity_id, value
FROM catalog_product_entity_varchar
WHERE attribute_id = ?
",
array($attribute_id)
);
/**
* Update eav_attribute to use the text table instead of the varchar.
*/
$connection->query("UPDATE eav_attribute SET backend_type = 'text' WHERE attribute_id = ?", array($attribute_id));
/**
* Delete the attribute values from the VARCHAR table.
*/
$connection->query("DELETE FROM catalog_product_entity_varchar WHERE attribute_id = ?", array($attribute_id));
$connection->commit();
$this->endSetup();
Yeah I confirm it's not supported.
You could try to update tables with SQL but it will be a pain ...
I would export all your products, apply the upgrade script that modify your attribute backend table and re-import all your products.
That way magento will fill automatically the new table (catalog_product_entity_text) used by your attribute.
After that, you should clean your varchar table to delete unused values linked to your products (values that will be never deleted nor updated as your attribute's product is now TEXT)

Insert default value when null is inserted

I have an Oracle database, and a table with several not null columns, all with default values.
I would like to use one insert statement for any data I want to insert, and don't bother to check if the values inserted are nulls or not.
Is there any way to fall back to default column value when null is inserted?
I have this code:
<?php
if (!empty($values['not_null_column_with_default_value'])) {
$insert = "
INSERT INTO schema.my_table
( pk_column, other_column, not_null_column_with_default_value)
VALUES
(:pk_column,:other_column,:not_null_column_with_default_value)
";
} else {
$insert = "
INSERT INTO schema.my_table
( pk_column, other_column)
VALUES
(:pk_column,:other_column)
";
}
So, I have to omit the column entirely, or I will have the error "trying insert null to not null column".
Of course I have multiple nullable columns, so the code create insert statement is very unreadable, ugly, and I just don't like it that way.
I would like to have one statement, something similar to:
INSERT INTO schema.my_table
( pk_column, other_column, not_null_column_with_default_value)
VALUES
(:pk_column,:other_column, NVL(:not_null_column_with_default_value, DEFAULT) );
That of course is a hypothetical query. Do you know any way I would achieve that goal with Oracle DBMS?
EDIT:
Thank you all for your answers. It seams that there is no "standard" way to achieve what I wanted to, so I accepted the IMO best answer: That I should stop being to smart and stick to just omitting the null values via automatically built statements.
Not exactly what I would like to see, but no better choice.
For those who reading it now:
In Oracle 12c there is new feature: DEFAULT ON NULL. For example:
CREATE TABLE tab1 (
col1 NUMBER DEFAULT 5,
col2 NUMBER DEFAULT ON NULL 7,
description VARCHAR2(30)
);
So when you try to INSERT null in col2, this will automatically be 7.
As explained in this AskTom thread, the DEFAULT keyword will only work as a stand-alone expression in a column insert and won't work when mixed with functions or expressions such as NVL.
In other words this is a valid query:
INSERT INTO schema.my_table
( pk_column, other_column, not_null_column_with_default_value)
VALUES
(:pk_column,:other_column, DEFAULT)
You could use a dynamic query with all rows and either a bind variable or the constant DEFAULT if the variable is null. This could be as simple as replacing the string :not_null_column_with_default_value with the string DEFAULT in your $insert.
You could also query the view ALL_TAB_COLUMNS and use nvl(:your_variable, :column_default). The default value is the column DATA_DEFAULT.
I think the cleanest way is to not mention them in your INSERT-statement. You could start writing triggers to fill default values but that's heavy armor for what you're aiming at.
Isn't it possible to restructure your application code a bit? In PHP, you could construct a clean INSERT-statement without messy if's, e.g. like this:
<?php
$insert['column_name1'] = 'column_value1';
$insert['column_name2'] = 'column_value2';
$insert['column_name3'] = '';
$insert['column_name4'] = 'column_value4';
// remove null values
foreach ($insert as $key => $value) {
if (is_null($value) || $value=="") {
unset($insert[$key]);
}
}
// construct insert statement
$statement = "insert into table (". implode(array_keys($insert), ',') .") values (:". implode(array_keys($insert), ',:') .")";
// call oci_parse
$stid = oci_parse($conn, $statement);
// bind parameters
foreach ($insert as $key => $value) {
oci_bind_by_name($stid, ":".$key, $value);
}
// execute!
oci_execute($stid);
?>
The better option for performance is the first one.
Anyway, as I understand, you don't want to repeat the insert column names and values due the difficult to make modifications. Another option you can use is to run an insert with returning clause followed by an update:
INSERT INTO schema.my_table
( pk_column, other_column, not_null_column_with_default_value)
VALUES
(:pk_column,:other_column, :not_null_column_with_default_value)
RETURNING not_null_column_with_default_value
INTO :insered_value
It seems to work with PHP.
After this you can check for null on insered_value bind variable. If it's null you can run the following update:
UPDATE my_table
SET not_null_column_with_default_value = DEFAULT
WHERE pk_column = :pk_column:
I would like to use one insert
statement for any data I want to
insert, and don't bother to check if
the values inserted are nulls or not.
Define your table with a default value for that column. For example:
create table myTable
(
created_date date default sysdate,
...
)
tablespace...
or alter an existing table:
alter table myTable modify(created_date default sysdate);
Now you (or anyone using myTable) don't have to worry about default values, as it should be. Just know that for this example, the column is still nullable, so someone could explicitly insert a null. If this isn't desired, make the column not null as well.
EDIT: Assuming the above is already done, you can use the DEFAULT keyword in your insert statement. I would avoid triggers for this.

Resources