"data":
"{\"thread\":{\"user_id\":76,\"parent_id\":\"139\",\"item_id\":\"178\",\"comment\":\"s\",\"updated_at\":\"2017-09-18
15:19:24\",\"created_at\":\"2017-09-18
15:19:24\",\"id\":140},\"user\":{\"id\":76,\"name\":\"Kavi\",\"lastname\":\"Arasan\",\"mobile\":\"822-034-1179\",\"email\":\"kayalmanimohana#gmail.com\",\"verified\":0,\"email_token\":\"1ATrlUoyWy\",\"created_at\":\"2017-09-15
16:47:59\",\"updated_at\":\"2017-09-18
15:18:57\",\"address\":null,\"city\":null,\"state\":null,\"country\":null,\"pin\":null,\"profile\":null,\"gender\":null,\"street_num\":null,\"provider\":null,\"provider_id\":null,\"is_delete\":null,\"username\":\"dummy\"}}",
i have data object like this in my db. How do i get the user id present within thread of data? Am using laravel
#kayal if you are still learning then this is good but sometime you should read the documentation
here is the method that you can do this easily
For Example
Assuming Table name test
+------------+
| id | data |
+------------+
| 1 | {...} |
+------------+
suppose you have Model Test.php
Then add a protected property $casts it is an array in this array add key => value key is column name and value will be in which type you want to cast like object or array in this case i am using object.
namespace App;
class Test extends Model
{
protected $casts = ['data' => 'object']; // add this property
in your controller
in this case i am using TestController.php
namespace App\Http\Controllers;
use App\Test;
class TestController extends Controller
{
public function seeUserId()
{
$test = Test::find(1); // or your query
$user_id = $test->data->thread->user_id; // you can access like this this is only example
}
public function saveData($data)
{
$test = new Test;
$test->data = $data; // don't use json_encode() just pass any object or array ;
$test->save();
}
laravel doc :- https://laravel.com/docs/5.5/eloquent-mutators#array-and-json-casting
foreach ($unread as $unr) {
$data = json_decode($unr->data,true);
$user_id = $data['thread']['user_id'];
}
This made it possible
Related
Im new to laravel, i am trying to query a specific table in my DB. I only have 1 data table and the standard user auth tables. I am getting a error: BadMethodCallException
Call to undefined method App\Figures::table().
Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Figures extends Model
{
}
controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Figures;
class figuresController extends Controller
public function figurespag2() {
$dummyDetails = Figures::table('figures')->where('name', 'batman');
return view ( 'pagination2.index' )->withUsers($dummyDetails);
}
route
Route::get ( '/pagination2', 'figuresController#figurespag2' );
I know it's going to be something obvious, but I am new to this.
this is wrong
$dummyDetails = Figures::table('figures')->where('name', 'batman');
Method 1---------- laravel eloquent
Model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Figures extends Model
{
protected $table = 'figures';
}
Controller
$dummyDetails = Figures::where('name', 'batman')->get();
and
Method 2 ---------- laravel Query Builder
$dummyDetails = \DB::table('figures')->where('name', 'batman')->get();
Use this you not need to define table name
public function figurespag2() {
$dummyDetails = Figures::where('name', 'batman')->get();
return view ( 'pagination2.index' )->withUsers($dummyDetails);
}
First you may need to know laravel model rules.
If you create a table name like "figures" (plural) you need to create its model by Figure (singular).
if you create a table other then this rule then you have to mentioned table name in model like this.
protected $table = "table_name";
you can access table with where condition in controller like this.
public function figurespag2() {
$dummyDetails = Figure::where('name', 'batman')->get();
return view ( 'pagination2.index' )->withUsers($dummyDetails);
}
Hope this may help you.
In my Project I've 2 tables:
MyAwesomeTable
ID | NAME | SOMEMOREINFO | ...
MySecondTable
ID | MyAwesomeTable_ID | SOMEOTHERDATA
Sorry for the weird formatting, but I do not know how to format tables in Stackoverflow correctly.
In my PHP I've got the following Model.
public class MySecondTable {
...
public function awesomeTable() {
return $this->hasOne('App\Models\MyAwesomeTable', 'id', 'MyAwesomeTable_ID');
}
}
When I'm trying to get the entries of my MySecondTable with the following code, the JSON which is generated contains the MyAwesomeTable_ID AND the resolved awesomeTable.
How can I achieve to only get the resolved awesomeTable, without needing to call something like removeColumns.
$entries = MySecondTable::with(['awesomeTable'])->get();
What the call gives me is:
{
...
'MyAwesomeTable_ID' : 1, // I Don't want this entry
'awesomeTable' : {
'id': 1,
'name' : 'some name',
...
}
}
If you don't want something to appear in the default select-list of a model, add that property to the $hidden array of that model,
public class MySecondTable {
// An array of properties that should not appear
// in the default select-list or JSON output
protected $hidden = ['MyAwesomeTable_ID'];
public function awesomeTable() {
// You can just define relation like this, the if you follow Laravel naming-conventions
return $this->hasOne(MyAwesomeTable::class);
// return $this->hasOne('App\Models\MyAwesomeTable', 'id', 'MyAwesomeTable_ID');
}
}
Laravel documentation
i'm using Laravel 5.3
and i'm trying to select from the database the values for the lang files,
i created a file and named it global.php
and inside the file i tried to do this:
use App\Dictionary;
$language_id = 1;
$dictionary = array();
$lables = Dictionary::where('language_id',$language_id)->get();
foreach($lables as $label):
$dictionary[$label->label] = $label->value;
endforeach;
return $dictionary;
now, this is working but i want to select the rows using the short_name field and not the id of the language
i want it to be something like this:
$lables = Dictionary::all()->language()->where('short_name', 'en')->get();
my database looks like this:
Languages
id
name // for example: English
short_name // for exmaple: en
Dictionary
id
key
value
language_id
and my models looks like this:
Language Model
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Language extends Model
{
use SoftDeletes;
protected $softDelete = true;
protected $dates = ['deleted_at'];
public function dictionary()
{
return $this->hasMany('App\Dictionary');
}
}
Dictionary Model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Dictionary extends Model
{
protected $table = 'dictionary';
public function language()
{
return $this->belongsTo('App\Language');
}
}
thank you for your help!
!!!UPDATE!!!
i added 1 more table called
Labels
id
label_name
and change the dictionary table to:
Dictionary
id
lable_id
value
language_id
how can i make this work so i can pull the label_name instead of the label_id
$lables = Dictionary::whereHas('language', function($query) {
$short_name = basename(__DIR__);
$query->where('short_name', $short_name);
})->pluck('value', 'label_id')->toArray();
You can use Laravel's whereHas() function as:
$lables = Dictionary::whereHas('language', function($query) {
$query->where('short_name', 'en');
})->get();
Update
If you want to get rid of your foreach() then you can use Laravel's pluck() function as:
$lables = Dictionary::whereHas('language', function($query) {
$query->where('short_name', 'en');
})->pluck('value', 'label')->toArray();
I guess it could be something like:
$lables = Dictionary::with('language')->where('short_name', 'en')->get();
After creating model, when I try to get his attributes, i get only fields in database that are filled.
----------------------------------------------
DB: | id | shopID | name | bottleID | capacity |
----------------------------------------------
| 1 | 8 | Cola | 3 | |
----------------------------------------------
In this case I need capacity attribute too, as empty string
public function getDrinkData(Request $request)
{
$drink = Drink::where('shopId', $request->session()->get('shopId'))->first();
if($drink) {
$drink = $drink->attributesToArray();
}
else {
$drink = Drink::firstOrNew(['shopId' => $request->session()->get('shopId')]);
$drink = $drink->attributesToArray(); // i want to get even empty fields
}
return view('shop.drink')->(['drink' => $drink])
}
But for later usage (in view) I need to have all attributes, including empty ones. I know that this code works as it should, but I don't know how to change it to detect all attributes.
The model attributes are populated by reading the data from the database. When using firstOrNew() and a record doesn't exist, it makes a new instance of the model object without reading from the database, so the only attributes it has will be the ones manually assigned. Additionally, since there is no record in the database yet, you can't just re-read the database to get the missing data.
In this case, you can use Schema::getColumnListing($tableName) to get an array of all the columns in the table. With that information, you can create a base array that has all the column names as keys, and null for all the values, and then merge in the values of your Drink object.
public function getDrinkData(Request $request)
{
// firstOrNew will query using attributes, so no need for two queries
$drink = Drink::firstOrNew(['shopId' => $request->session()->get('shopId')]);
// if an existing record was found
if($drink->exists) {
$drink = $drink->attributesToArray();
}
// otherwise a new model instance was instantiated
else {
// get the column names for the table
$columns = Schema::getColumnListing($drink->getTable());
// create array where column names are keys, and values are null
$columns = array_fill_keys($columns, null);
// merge the populated values into the base array
$drink = array_merge($columns, $drink->attributesToArray());
}
return view('shop.drink')->(['drink' => $drink])
}
If you were using firstOrCreate(), then a new record is created when one doesn't exist. Since there a record in the database now, you could simply re-read the record from the database to populated all of the model attributes. For example:
public function getDrinkData(Request $request)
{
$drink = Drink::firstOrCreate(['shopId' => $request->session()->get('shopId')]);
// If it was just created, refresh the model to get all the attributes.
if ($drink->wasRecentlyCreated) {
$drink = $drink->fresh();
}
return view('shop.drink')->(['drink' => $drink->attributesToArray()])
}
What if you were to explicitly declare all the fields you want back.
An example of something I do that is a bit more basic as I'm not using where clauses and just getting all from Request object. I still think this could be helpful to someone out there.
public function getDrinkData(Request $request)
{
// This will only give back the columns/attributes that have data.
// NULL values will be omitted.
//$drink = $request->all();
// However by declaring all the attributes I want I can get back
// columns even if the value is null. Additional filtering can be
// added on if you still want/need to massage the data.
$drink = $request->all([
'id',
'shopID',
'name',
'bottleID',
'capacity'
]);
//...
return view('shop.drink')->(['drink' => $drink])
}
You should add a $fillable array on your eloquent model
protected $fillable = ['name', 'email', 'password'];
make sure to put the name of all the fields you need or you can use "*" to select all.
If you already have that, you can use the ->toArray() method that will get all attributes including the empty ones.
I'm using the same thing for my Post model and it works great with all fields including empty ones.
My model looks like this:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
protected $fillable = ["*"];
public function comments()
{
return $this->hasMany(Comment::class);
}
}
Do you need to set the $drink variable again after checking the $drink variable?
you can check the following code?
public function getDrinkData(Request $request)
{
$drink = Drink::where('shopId', $request->session()->get('shopId'))->first();
if(!count($drink)>0) {
$drink = Drink::firstOrNew(['shopId' => $request->session()->get('shopId')]);
}
return view('shop.drink')->(['drink' => $drink]); or
return view('shop.drink',compact('drink'));
}
hope it will help. :) :)
You can hack by overriding attributesToArray method
class Drink extends Model
{
public function attributesToArray()
{
$arr = parent::attributesToArray();
if ( !array_key_exist('capacity', $arr) ) {
$arr['capacity'] = '';
}
return $arr;
}
}
or toArray method
class Drink extends Model
{
public function toArray()
{
$arr = parent::toArray();
if ( !array_key_exist('capacity', $arr) ) {
$arr['capacity'] = '';
}
return $arr;
}
}
then
$dirnk->toArray(); // here capacity will be presented even it null in db
I'm making a data filter and I need to filter a column with json saved data. The table structure is similar to this:
____________________________________
| id | name | tags |
|____|_________|___________________|
| 1 | example | ["3","4","5","6"] |
|____|_________|___________________|
Any idea how to filter this column by tags using Eloquent ORM included with Laravel?
Use the getter get<Column>Attribute:
class YourModel extends Eloquent {
public function getTagsAttribute($value)
{
return json_decode($value);
}
}
You could use mySql JSON_CONTAINS function since it is optimized on the DB level. Unfortunately Eloquent doesn't (?) provide wrappers for functions like this so you can fall back to plain SQL and create your models from the results.
This is an example that returns a Collection of Models:
class myModel extends Eloquent {
protected $casts = [
'json_column' => 'array', // this is JSON type in the DB
];
/**
* Returns a Collection of 'myModel' that have $search value
* stored in the 'json_column' array
*
* #param string $search
* #return \Illuminate\Database\Eloquent\Collection
*/
public static function findInJsonColumn($search){
$data = \DB::select("SELECT * FROM table_name WHERE JSON_CONTAINS(json_column, '[\"$search\"]')");
return self::hydrate($data);
}
}
class YourModel extends Eloquent {
public function getTagsAttribute($value)
{
parent::where($value)->get();
}
}