jarektkaczyk / eloquence Goto Github PK
View Code? Open in Web Editor NEWExtensions for the Eloquent ORM
Home Page: http://softonsofa.com
License: MIT License
Extensions for the Eloquent ORM
Home Page: http://softonsofa.com
License: MIT License
Hi,
Two days of fruitless effort have led me to post here.
Very Simple - Laravel 5.2.latest (PHP 5.9.11).
Trying to use Mappable on a Model (or \Eloquent) and cannot access the mapped properties by name.
Any clues?
Example is below.
<?php
namespace App;
use Illuminate\Support\Facades\App;
use Illuminate\Database\Eloquent\Model;
use Sofa\Eloquence\Eloquence;
use Sofa\Eloquence\Mappable;
class FormInfo extends Model
{
use Eloquence, Mappable;
protected $maps = [
'createdAt' => '_CREATION_DATE',
'complete' => '_IS_COMPLETE',
'id' => '_URI',
'lastUpdated' => '_LAST_UPDATE_DATE',
'submissable' => 'formInfoSubmissionAssociation._IS_SUBMISSION_ALLOWED',
];
protected $appends = [
'createdAt',
'complete',
'id',
'lastUpdated',
'submissable'
];
protected $casts = [
'_CREATION_DATE' => 'datetime',
'_LAST_UPDATE_DATE' => 'datetime',
'_SUBMISSION_DATE' => 'datetime',
'_MARKED_AS_COMPLETE_DATE' => 'datetime',
'_IS_COMPLETE' => 'boolean'
];
protected $table = '_form_info';
protected $primaryKey = '_URI';
public $timestamps = false;
protected $connection = 'nothing';
public $incrementing = false;
//set the Connection name from IoC
public function __construct()
{
$this->connection = App::make('DBConnection')->name();
}
Hello there,
I added the searchable columns to my model and added "Customer::search($string)->get();" to my controller, however I'm encountering the following error:
"SQLSTATE[HY000]: General error: 8120 General SQL Server error: Check messages from the SQL Server [8120](severity 16) [(null)](SQL: select * from %28select [ASC_CUS_TBL_OLD].*, max%28case when [ASC_CUS_TBL_OLD].[CUS_INV_NAME] = OAKWOOD then 15 else 0 end + case when [ASC_CUS_TBL_OLD].[CUS_INV_NAME] like OAKWOOD% then 5 else 0 end + case when [ASC_CUS_TBL_OLD].[CUS_INV_NAME] like %OAKWOOD% then 1 else 0 end%29 as relevance from [ASC_CUS_TBL_OLD] where %28[ASC_CUS_TBL_OLD].[CUS_INV_NAME] like %OAKWOOD%%29 group by [ASC_CUS_TBL_OLD].[CUS_UNIQUE]%29 as [ASC_CUS_TBL_OLD] where [relevance] >= 0.25 order by [relevance] desc)"
I'm using sqlsrv for the database driver.
Any ideas?
Thanks
When saving a model that uses the Mappable
trait, are we unable to have aliases with matching column names? For example:
class MyModel extends \Eloquent {
use Eloquence, Mappable;
protected $fillable = ['first_name'];
protected $maps = [
'first_name' => 'first_name',
// ...
];
}
// ...
$model = new MyModel;
$model->first_name = 'Jon';
$model->save();
The save is successful but the value of first_name
is not persisted to the database. I can work around the issue by having an alias of a different name. Using version 0.4.13
and Postgres.
Hey there! What would the best approach be to get some help from Phpstorm upon typing User::se
and then ctrl + space
?
Hello,
I'm following the installation manual, but get an "'Sofa\Eloquence\ServiceProvider' not found" error.
I added "sofa/eloquence": "~5.1@dev" to my composer.json and "Sofa\Eloquence\ServiceProvider::class," to my config/app.php.
And run "php composer.phar update".
What could be the problem?
[RuntimeException]
Error Output: PHP Fatal error: Class 'Sofa\Eloquence\ServiceProvider' not found in /.../vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php on line 146
Customer has many Addresses, and has one primary address defined in foreign-key column primary_address_id
Addresses belongs to one Customer
Customer has an attribute defined:
public function getFullAddressAttribute()
{
//get primary address's fullAddress attribute
$address = Address::find($this->primary_address_id);
if($address)
return $address->fullAddress;
//if customer does not have primary address defined, return a blank array []
return [];
}
Addresses has an attribute with same name defined:
public function getFullAddressAttribute()
{
//get each line and combine into one array
return [
($this->customer_id ? "To: ".$this->customer->name : ''),
$this->line_1.',', //lines are inserted with comma ',' and space ' '
($this->line_2 ? $this->line_2.', ' : ''), //so that it should return something like:
($this->line_3 ? $this->line_3.', ' : ''), //['123 main st., ', 'Apt 8F, ', 'Los Angeles, ' CA ', '90010 ']
$this->city.', '.
$this->province.' '.
$this->zipcode.' '.
$this->country
];
}
Now I want to fetch a customer's addresses:
Customer::rightJoinRelations('addresses')->select('addresses.*')->where('customers.id', 2);
and it returs:
{"id":2,"customer_id":2,"line_1":"28099 Nicolas Mill","line_2":"Apt. 964","line_3":null,"city":"Emardville","province":"CO","country":null,"zipcode":"14319-7111","phone":"","note":"Blanditiis aut vitae beatae blanditiis.","created_at":"2015-07-14 15:32:04","updated_at":"2015-07-14 15:32:04","fullAddress":[]}
From the results you can see it returns Addresses table columns fine, but notice at the end "fullAddress" is blank. However, in Address model, as you can see, there is no way it could return an empty array.
The other way around, if I want to fetch an address's customer, I do
Address::rightJoinRelations('customer')->select('customers.*')->where('addresses.id', 2);
It returns Customers table columns fine, except "fullAddress" returns
"fullAddress":["",",","","",", "]
Notice it tried to insert the lines with comma and space, which should be done in Address model. The only situation this could happen is when in Customers table primary_address_id is defined, and the address it points to is all empty, which is not possible, as the fields are required in database and in model.
So I guess the problem was that, rightJoinRelations fetches fullAddress from the model left to it, instead of the one on the right, even if I specified in select('tableName.*')
clause.
Hi,
Under fresh install, Type de serveur: MySQL - Version du serveur: 5.5.37-0ubuntu0.13.10.1 - (Ubuntu),
I've an error
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1170 BLOB/TEXT column 'm
eta_value' used in key specification without a key length (SQL: alter table
meta_attributes
add index meta_attributes_meta_key_meta_value_index(met a_key
, meta_value
))
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1170 BLOB/TEXT column 'm
eta_value' used in key specification without a key length
I just create the migration file and copie paste the migration sample from sofa/eloquence/src/Metatable/CreateMetaAttributesTable.php without the namespace ....
What sorte of meta_value table could I try to test Eloquence\Metable ?
There will be lots of cases where the match type will differ based on the data "column" we are looking to match with. Since the fulltext search method is much more computationally expensive than the others, it would be a significant performance enhancement if it were possible to specify which relationship sets are searched via fulltext method and which won't. Effectively, the intent is to be able to make use of table indexes as much as possible without forbidding it on a few columns. Given the nested query method used by this package, it should be doable.
So, considering a "Project" model with various pick list-type relationships, here is a likely scenario:
This is a fantastic enhancement package, in particular the Mappable feature is enabling very straightforward and efficient UI column sorting even using nested relationships. Awesome stuff!
For example,
class Customer extends Model {
use Eloquence;
public function getBriefAttribute()
{
return $this->name;
}
}
Is it possible to include this custom brief attribute in search result?
So I can do this in javascript:
// after fetch search result in var response
var brief = response.brief
I was trying so hard to return custom attributes in search results. Hope you can give me some hints. Thanks.
Sorry wrong repo and I can't delete this :(
When my model code is this, seeding doesn't work
<?php namespace App;
use Sofa\Eloquence\Model;
use Sofa\Eloquence\Mutable;
class LetterType extends Model {
use Mutable;
protected $fillable = ['title', 'acronym', 'description'];
/**
* Attributes getter mutators @ Eloquence\Mutable
*
* @var array
*/
protected $getterMutators = [
];
/**
* Attributes setter mutators @ Eloquence\Mutable
*
* @var array
*/
protected $setterMutators = [
'acronym' => 'trim',
];
protected static $rules = [
'title' => 'required',
'acronym' => 'required',
];
}
Seeding only works when I change to:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
use Sofa\Eloquence\Contracts\CleansAttributes;
use Sofa\Eloquence\Contracts\Validable as ValidableContract;
use Sofa\Eloquence\Eloquence;
use Sofa\Eloquence\Mappable;
use Sofa\Eloquence\Mutable;
use Sofa\Eloquence\Validable;
class LetterType extends Model implements ValidableContract, CleansAttributes {
use Eloquence, Mutable, Validable;
protected $fillable = ['title', 'acronym', 'description'];
/**
* Attributes getter mutators @ Eloquence\Mutable
*
* @var array
*/
protected $getterMutators = [
];
/**
* Attributes setter mutators @ Eloquence\Mutable
*
* @var array
*/
protected $setterMutators = [
'acronym' => 'trim|strtoupper',
];
/**
* Rules for field attributes
* Available rules as described in the laravel docs:
* @link http://laravel.com/docs/5.0/validation#available-validation-rules
*/
public static $rules = [
'title' => 'required',
'acronym' => 'required',
];
}
This is strange to me because for my User model, extending Sofa\Eloquence\Model gives me no issue in seeding. But for my LetterType model, it does.
Hey.
If we use the validable trait along with model factory that simply is going to break very quickly. An example to that is that in my system I'm creating a user without the user "knowledge" and I do not persist store an email for him. When the user will manually register he will need to provide the email. The issue is that in my model factory I'm randomly creating users that may or may not have email addresses.
When I'm doing it in my code I'm simply calling the skipValidation
method, however I'm not sure how I can do that with model factories. Basically it means that some users are not persisted to my DB when trying to seed it.
Hi there,
I am using Laravel version 5.1.16. I am trying to use pagination with eloquence and while it does return the correct results for the data, all of the meta data is not correct (total, next page url, etc.). Is this a known problem? If so, is there a way to get some of that meta data (mainly the total) from eloquence using a different method until it is fixed?
Here is my basic setup.
Model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Sofa\Eloquence\Eloquence;
class Product extends Model
{
use Eloquence;
protected $searchableColumns = ['name','number','description'];
}
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use App\Models\Product;
class SearchController extends Controller
{
public function searchProducts(Request $request)
{
$keywords = $request->get('keywords');
$results = Product::search($keywords)->paginate(5);
return $results;
}
}
Now if I try to query this controller with a search term that I know will provide 7 results, here is my result:
{
total: 0,
per_page: 5,
current_page: 1,
last_page: 0,
next_page_url: null,
prev_page_url: null,
from: 1,
to: 2,
data: [...]
}
What is contained in the data field is actually correct and it's the first 5 results. However, as you can see, all of the meta data is not correct. Then if I manually add the page=2
query parameter to my route, I do load the remaining 2 records in the data field. However, again all of the meta data is wrong.
Any ideas? All help would be appreciated!
Hello,
First, I wanted to congratulate you for this very good package, thank you.
It seems that searchable is broken if we querying throught a polymorphic relationship.
select count(*) as aggregate from (select `customers`.*,
max(case when `customers`.`name` = term then 15 else 0 end
+ case when `customers`.`name` like term% then 5 else 0 end
+ case when `customers`.`name` like %term% then 1 else 0 end
+ case when `addresses`.`name` = term then 15 else 0 end
+ case when `addresses`.`name` like term% then 5 else 0 end
+ case when `addresses`.`name` like %term% then 1 else 0 end) as relevance
from `customers`
left join `addresses` on `addresses`.`adressable_id` = `customers`.`id`
and `addresses`.`adressable_type` = %term%
where (`customers`.`name` like %term% or `addresses`.`name` like ?)
group by `customers`.`id`) as `customers` where `relevance` >= 1
I am trying to store an array of data as a meta attribute. This attribute gets stored as JSON with a meta_type
of StdClass
.
Now when I retrieve a model directly and retrieve the meta attribute like this Post::first()->options
everything is working fine. Now comes the weird issue.
When I want to retrieve the model through a relationship and try to access the meta attribute like this Category::first()->posts()->first()->options
I get the following exception.
Argument 1 passed to Sofa\Eloquence\Metable\AttributeBag::addInstance() must be an instance of Sofa\Eloquence\Metable\Attribute, string given, called in /home/vagrant/Code/homestead/vendor/sofa/eloquence/src/Metable/AttributeBag.php on line 66 and defined
When I dump the value that is passed down in Line 66 it is the value of the meta_value
column instead of an Attribute
instance.
What could cause this issue? I am trying to figure it out but can't really find anything.
Laravel 5.1 introduced BC breaking changes in illuminate\database
among others, so a new branch for L5.1+ will be created.
I am trying to use the Validable
Trait with a Model which as one column that is an array and because of that it gets stored as JSON.
The issue is that validation will always fail because $this->getValidator()->setData($this->getAttributes());
in the Validable
Trait runs with the JSON representation of the column so if it looks for $my_array['field1']
it won't be able to find it since the value of the my_array
column is a string and not an array.
Model
use Sofa\Eloquence\Eloquence;
use Sofa\Eloquence\Validable;
use Sofa\Eloquence\Contracts\CleansAttributes;
use Sofa\Eloquence\Contracts\Validable as ValidableContract;
class SomeModel extends Eloquent implements ValidableContract, CleansAttributes
{
use Eloquence, Validable;
protected $casts = ['my_array' => 'array'];
protected static $businessRules = [
'my_array.field1' => 'required',
'my_array.field2' => 'required',
'my_array.field3' => 'required',
];
}
I thought about using the Mutator
Trait instead of Laravel's built in $casts
attribute but this always results in Allowed memory size exceeded...
.
protected $getterMutators = ['my_array' => 'json_decode'];
protected $setterMutators = ['my_array' => 'json_encode'];
Create a new record is done like this.
SomeModel::create([
'field' => 'some field value',
'my_array' => [
'field1' => 'value',
'field2' => 'value',
'field3' => 'value',
],
]);
How would I validate a field that is cast to a different type since it isn't working at the moment?
Not related to #32
I have 2 model, A and B. A hasMany B.
Both model extends \Sofa\Eloquence\Model
I create a ServiceProvider to listen for the saved and deleted event for model B
B::saved(function ($b) {
$b->a()->first()->update_metric();
return true;
});
However, this is always failed. When I track the cause, I use this code in update_metric()
method:
public function update_metric() {
//code to update properties in model A
$this->save();
\Log::debug($this);
\Log::debug($this->getUpdateRules());
\Log::debug($this->getValidationErrors());
}
From the debug log, I saw the update rules are for model B, not the model A. I have try to change the code in event listener:
A::find($b->a_id)->update_metric();
But still, the update rules
is still the rules for model B, not model A. When I read the source code, I suspect that this is because the Validable trait use the static. So, while listening the saved
event for the model B, the rules is still filled with the rules for model B and when I try to update another model inside the event listener, the rules carried on and making the save() failed.
For now, I'll use skipValidation()
as a workaround.
My validator Factory is not being set because in the src/Validable:162
if (function_exists('app') && isset(app()['validator'])) {
Although the app()['validator'] has the Factory, the isset allways returns false.
I'm using Lumen, in a PHP5.6.10 env
Hey,
So I said on my last PR (#1) we have a problem because we have both rewrite setAttribute
method.
I can create a PR on the Laravel repository to allow some hook in Eloquent's process. But if it's rejected, we need to create a new Trait to allow hooks in Eloquent.
What do you think of that?
I'm using a table join, but can't figure out how to search on a column from the joined table. I know that I can use columns from a table with a relationship, but can I do it on a straight joined table?
Here is what I'm trying:
User::leftJoin('users_profiles', 'users_profiles.user_id', '=', 'profile.id')
->search($string, ['username' => 10, 'users_profiles.email' => 20, 'users_profiles.firstname' => 5])
->get();
Gives an error:
Fatal error: Uncaught exception 'BadMethodCallException' with message 'Call to undefined method Sofa\Eloquence\Query\Builder::users_profiles()' in /vendor/illuminate/database/Query/Builder.php:2161
Any idea how I can search joined tables without creating relationships in the model instead?
Hello there,
Just wondering whether anyone has got this working with Lumen at all? Just tried using it, no errors are being thrown, but then again the desired functionality is not working either. This is my model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Sofa\Eloquence\Eloquence;
use Sofa\Eloquence\Mappable;
class Customers extends Model
{
use Eloquence, Mappable;
protected $maps = [
'CUS_UNIQUE' => 'id'
];
protected $table = 'ASC_CUS_TBL_OLD';
protected $fillable = [
'id',
'name',
'contacts',
'addresses',
'credit_limit'
];
Any ideas?
Cheers
i have some issues when using search a where clause and laravels paginate (no issue when removing one of them).
works in 5.1.8, broken in 5.1.9.
$results = Aura::search(["*" . $query . "*"], true)->isLive()->sortable()->paginate(20);
works in 5.1.8 + 5.1.9:
$results = Aura::search(["*" . $query . "*"], true)->sortable()->paginate(20);
scopeIsLive:
return $query->where('auras.status','=', Config::get('constant.aura.status.online'));
caused by
laravel/framework@4c48912
it removes the search bindings for the paginate query, leading to:
Next exception 'Illuminate\Database\QueryException' with message 'SQLSTATE[HY093]: Invalid parameter number (SQL: select count(*) as aggregate from (select `auras`.*, max(case when `auras`.`title` = 2 then 300 else 0 end + case when `auras`.`title` like ? then 100 else 0 end + case when `auras`.`title` like ? then 20 else 0 end + case when `auras`.`description` = ? then 150 else 0 end + case when `auras`.`description` like ? then 50 else 0 end + case when `auras`.`description` like ? then 10 else 0 end + case when `categories`.`title` = ? then 75 else 0 end + case when `categories`.`title` like ? then 25 else 0 end + case when `categories`.`title` like ? then 5 else 0 end) as relevance from `auras` left join `aura_categories` on `aura_categories`.`aura_id` = `auras`.`id` left join `categories` on `aura_categories`.`category_id` = `categories`.`id` where (`auras`.`title` like ? or `auras`.`description` like ? or `categories`.`title` like ?) group by `auras`.`id`) as `auras` where `relevance` >= 8.75 and `auras`.`status` = ?)'
is there a way to work around this issue or should i adress this at laravel/framework?
If I have a model with a qualified table name specified:
protected $table = "core.accounts";
This causes the Searchable trait to crap out. It looks like it builds the sub query just fine, but then tries to alias it back to the qualified name. So the query ends up looking like:
select * from (select `core`.`accounts`.*,(max ... rest of search here ... group by `core`.`accounts`.`id`) as `core`.`accounts` where `relevance` >= 0.25 order by `relevance` desc
Aliasing the table name back to core
.accounts
is causing MySQL to throw a Syntax error. (v5.7.9)
Is this a known issue with a workaround?
Hello.
I have some tests which call getCreatedRules()
on a User
model first and after few tests it's calling the getCreatedRules()
on a Profile
model and for some odd reason the rules that are being returned are the User
rules. When I run the Profile
tests alone, everything works just fine.
The weird thing is that tests shouldn't depend on each other but somehow one test affects the other?
a solution that I found for the time being:
/**
* Get all the validation rules for this model.
*
* @return array
*/
public static function getCreateRules()
{
if (!eval('\\'.get_called_class().'::$rulesMerged;')) {
static::$rulesMerged = static::gatherRules();
}
return static::$rulesMerged;
}
another solution is to simply omit the if
statement and always gather the rules but that can be expensive call. I wonder why this issue is happening. I was sure that the static
keyboard will return the called class but it seems like it doesn't? the PHP version is 5.6.10
Hi,
Can we search by multiple fields?
For example I want search by first and last name. If I search John Doe
I want get the result for columns firstname
and lastname
with concatenation.
firstname lastname
or lastname firstname
And can we use a filter panel to search with multiple input ?
For example in my case:
First name, Last name, etc
$query = [];
$input = [];
if($request->get('company_name')) {
$query[] = 'company_name';
$input[] = 'company_name';
}
if($request->get('firstname')) {
$query[] = 'contacts.firstname';
$input[] = 'firstname';
}
if($request->get('lastname')) {
$query[] = 'contacts.lastname';
$input[] = 'lastname';
}
$clients = Client::search($request->only($input), $query)->with('contacts')->get();
Can I use AND operator to search only by fields filled by the user ?
Thx
If I insert an orderBy()
into a searchable query, the data returned is still ordered by relevance first, and only applies the ordering within groups of results with the same relevance.
For instance, let's take a basic searchable query:
Item::search('test')->orderBy('name')->get()
Expected output:
[
{ name: 'A Item', relevance: 4 }
{ name: 'B Item', relevance: 8 }
{ name: 'C Item', relevance: 4 }
{ name: 'D Item', relevance: 8 }
]
Actual output:
[
{ name: 'B Item', relevance: 8 }
{ name: 'D Item', relevance: 8 }
{ name: 'A Item', relevance: 4 }
{ name: 'C Item', relevance: 4 }
]
It still sorts by relevance first before applying the orderBy()
. This makes it impossible to sort results alphabetically. If you wanted to order by the relevance and something else then you could always add an orderBy('relevance')
into your query, but I don't think this should be forced in if another orderBy statement exists. Can this be fixed easily?
Everything works well if I have less than 4 searchableColumns. As soon as I have more than 4 searchable columns the search does not behave as expected.
If I have a field with the value "This is a test" and I query with a string "test" the search works great as long as I have less than 4 searchable columns defined on the model. As soon as I have more than 4 searchable columns the search will not work as "test" (returns 0 results) but it will work if I search "is a test".
This returns a result
The model:
protected $searchableColumns = ['name','building_phone', 'manager_phone', 'manager_email', 'street_address', 'city', 'postal_code', 'country', 'instructions', 'user.first_name', 'user.last_name'];
The controller:
$term = "is a test";
$buildings = Building::search($term)->paginate(10);
This returns no results
The model:
protected $searchableColumns = ['name','building_phone', 'manager_phone', 'manager_email', 'street_address', 'city', 'postal_code', 'country', 'instructions', 'user.first_name', 'user.last_name'];
The controller:
$term = "test";
$buildings = Building::search($term)->paginate(10);
This returns results
The model:
protected $searchableColumns = ['name','building_phone', 'manager_phone', 'manager_email'];
The controller:
$term = "test";
$buildings = Building::search($term)->paginate(10);
Any ideas? Thanks so much.
Hi , would it be possible to use outside of laravel ?
Im using slim with eloquent .
Thanking your in advance .
When I add other traits to my model, I got an error:
vagrant@homestead:~/Code/Laravel$ php artisan tinker
Psy Shell v0.5.2 (PHP 5.6.11-1+deb.sury.org~trusty+1 — cli) by Justin Hileman
>>> namespace neb;
=> null
>>> $p=new Page;
=> neb\Page {#827}
>>> $p->title='something';
=> "something"
>>> $p->save();
PHP warning: array_filter() expects parameter 1 to be array, object given in /home/vagrant/Code/Laravel/vendor/sofa/eloquence/src/Metable.php on line 615
My Page model:
<?php
namespace neb;
use Sofa\Eloquence\Eloquence;
use Sofa\Eloquence\Metable;
use \Codefocus\NestedSet\NestedSetTrait;
class Page extends \Eloquent
{
use Eloquence, Metable, NestedSetTrait;
protected $nestedSetColumns = [
'left' => 'left',
'right' => 'right',
'parent' => 'parent_id',
'depth' => 'depth',
'group' => 'group',
];
}
If I remove Eloquent and Metable traits, I have no error:
vagrant@homestead:~/Code/Laravel$ php artisan tinker
Psy Shell v0.5.2 (PHP 5.6.11-1+deb.sury.org~trusty+1 — cli) by Justin Hileman
>>> namespace neb;
=> null
>>> $p=new Page;
=> neb\Page {#827}
>>> $p->title='something';
=> "something"
>>> $p->save();
=> true
>>> $p->toArray();
=> [
"title" => "something",
"left" => 1,
"right" => 2,
"depth" => 0,
"updated_at" => "2015-08-12 08:49:00",
"created_at" => "2015-08-12 08:49:00",
"id" => 1,
]
>>>
The Page model:
<?php
namespace neb;
use Sofa\Eloquence\Eloquence;
use Sofa\Eloquence\Metable;
use \Codefocus\NestedSet\NestedSetTrait;
class Page extends \Eloquent
{
use NestedSetTrait;
protected $nestedSetColumns = [
'left' => 'left',
'right' => 'right',
'parent' => 'parent_id',
'depth' => 'depth',
'group' => 'group',
];
}
I tried the basic Metable install, but when I want to access the meta info with toArray()
, I got an error:
vagrant@homestead:~/Code/Laravel$ php artisan tinker
Psy Shell v0.5.2 (PHP 5.6.11-1+deb.sury.org~trusty+1 — cli) by Justin Hileman
>>> namespace neb;
=> null
>>> $p=new Page;
=> neb\Page {#827}
>>> $p->title='something';
=> "something"
>>> $p->nonexistentattribute='nothing';
=> "nothing"
>>> $p->save();
=> true
>>> $p = Page::latest()->first();
=> neb\Page {#871
id: 1,
slug: "",
title: "something",
content: "",
searchable: "",
created_at: "2015-08-12 08:55:39",
updated_at: "2015-08-12 08:55:39",
author: "",
language: "",
subtitle: "",
parent_id: null,
left: null,
right: null,
depth: null,
group: null,
description: "",
type: "",
is_link: 0,
link: "",
status: 0,
header: "",
is_list: 0,
show_when_list: 1,
order_when_list: "",
publish_at: "0000-00-00 00:00:00",
hide_at: "0000-00-00 00:00:00",
show_in_menu: 0,
is_featured: 0,
}
>>> $p->nonexistentattribute;
=> "nothing"
>>> $p->toArray();
PHP error: Argument 1 passed to Sofa\Eloquence\Metable\AttributeBag::addInstance() must be an instance of Sofa\Eloquence\Metable\Attribute, string given, called in /home/vagrant/Code/Laravel/vendor/sofa/eloquence/src/Metable/AttributeBag.php on line 66 and defined in /home/vagrant/Code/Laravel/vendor/sofa/eloquence/src/Metable/AttributeBag.php on line 74
There is an error with the arrays again...
Hello there,
I'm currently facing an issue with timestamps not being updated in the database. I've mapped them as follows:
protected $maps = [
'id' => 'CUS_UNIQUE',
'name' => 'CUS_INV_NAME',
'email' => 'CUS_EMAIL_ADD',
'customer_id' => 'CUS_CODE',
'created_at' => 'CUS_CREATED',
'updated_at' => 'CUS_UPDATED'
];
I would imagine that the timestamps that get created automatically would map to the columns I've specified? Perhaps there's something else happening here that's causing the issue
Any ideas?
Cheers
Dan
Hey guys,
I'm currently trying your amazing package. During documentation reading I came to the point where you extend the model like this:
class User extends \Eloquent {
}
Are you sure this works? In my opinion there is no class with that name. What you mean is Illuminate\Database\Eloquent\Model, right?
Hi,
Upon saving I had an issue with save returning false. Upon calling getValidationErrors
It told me that it failed a validation rule where 2 field need to be different.
In this case 1 of my field is null, and another is an integer. So it is indeed different and should pass validation.
Given that it passes the FormRequests but fails at save(). Hence I decide to file the issue here.
Hey,
I've got two tables: tasks and tags.
tasks: id, title, text
tags: id, task_id, tag_name
How to merge the results of the two tables.
At the end, I want to display a task with the belonging tags.
Hi there!
Just letting you know that the term Eloquence has been in use as a package name (my own) for a while, check it out. Basically just provides some basic extensions since Laravel 4.x. It's very similar in the sense that it's Laravel based, and is built to work with Eloquent.
https://github.com/kirkbushell/eloquence
Adding this here as some may get confused.
Hey,
Anyone know if it's possible for the search function to ignore HTML tags while searching through a model?
Here's an example of what I mean:
Let's say I have a table called contacts
with a column called contacts.description
. In description
, HTML tags are saved so we could have something like '<p>Is a person</p>'
as a description of a contact
.
Right now, running something like this:
$q = 'Is a person';
Contact::search($q);
Results in zero matches unless I change query to $q = '<p>Is a person</p>'
.
Note:
I'm currently using the 5.1 branch of eloquence.
Hi,
I have a model like this:
class Account extends Model
{
...
protected $fillable = ['account_type', 'city', ...];
public function city()
{
return $this->belongsTo('Ipalaus\Geonames\Eloquent\Name', 'geonames_name_id');
}
public function account_type()
{
return $this->belongsTo(AccountType::class);
}
...
}
and my table is like this:
table: accounts
...
field: geoname_id
field: account_type_id
...
I want to map this 2 attributes to:
geoname_id -> city
account_type_id -> account_type
in my model, if I use mapping:
protected $maps = [
'account_type' => 'geoname_id',
'city' => 'account_type_id',
];
but like this it returns just id not the object, i'm doing something wrong ??
Thanks
Hey @jarektkaczyk search is not working on the related models. Code is below :
1. My model (member.php)
protected $searchableColumns = [
'member_code' => 20,
'name' => 20,
'contact' => 20,
'Plan.plan_name' => 20,
];
//Relationships
public function Plan()
{
return $this->belongsTo('App\Plan','plan_id');
}
When I search for any plan name for example i search for 'Gym + Cardio 1 month' , I get all the records with plan names having the word 'Gym' in it irrespective of the other 2-3 words after it.
Any fix or am i doing something wrong? Help!
As soon you use the Eloquence Trait in one of your Models it breaks the Serialization.
What worked before now won't work anymore.
I use redis as a cache store and it no longer stores my models.
I get a "serialization of 'Closure' is not allowed" Exception.
Maybe you could try to swap it with SuperClosure wich is already part of Laravel.
Nice package though I really like it unfortunately i cannot continue using it. Until it can serialize my models again.
Kind regards
Alex
The case happens when two Mappable Models are instantiated inside a factory (somewhere else, maybe?).
Please consider the following factory:
$factory->define(Pedido::class, function (Faker\Generator $faker) use ($factory) {
$cliente = $factory->create('Cliente');
return [
'cliente_id' => $cliente->id,
'preco_entrega' => $faker->randomFloat(2, 3, 6),
];
});
Both Models, (Cliente and Pedido) are mapped models. The problem is when Cliente
is created, it populates the static property $mappedAttributes
, which in turn is still filled when the factory tries to create Pedido
. So when Pedido is beeing created his $mappedAttributes is defined as of the Cliente class, resulting in mysql Unkown columns
exceptions.
Hi, I am using Searchable in my model and I specified these columns:
protected $searchableColumns = [
'translations.title' => 10,
'variants.sku' => 20,
];
However as it calculates the relevance as 7.5 it uses comma as delimiter instead of a dot.
We are using comma in our country, so the server config is set to this value, however I think the Query Builder should make sure to use the dot no matter how the system is set.
The query looks like this:
select count(*) as aggregate from (select `items`.*, max(case when `item_translations`.`title` = stul then 150 else 0 end + case when `item_translations`.`title` like stul% then 50 else 0 end + case when `item_translations`.`title` like %stul% then 10 else 0 end + case when `item_variants`.`sku` = stul then 300 else 0 end + case when `item_variants`.`sku` like stul% then 100 else 0 end + case when `item_variants`.`sku` like %stul% then 20 else 0 end) as relevance from `items` left join `item_translations` on `item_translations`.`item_id` = `items`.`id` left join `item_variants` on `item_variants`.`item_id` = `items`.`id` where (`item_translations`.`title` like %stul% or `item_variants`.`sku` like %stul%) group by `items`.`id`) as `items` where `relevance` >= 7,5)
Also I am not sure how it handles the queries, for example when I search for "stul a kleste"
it produces
...
`item_translations`.`title` = stul a kleste then 150 else 0
...
I think there should be quotation marks around it to make it more query safe, or is MySQL clever enough to figure it out for each example?
I am not exactly sure if it's a problem in your package, or in Laravel's QueryBuilder though, didn't go through the code to find out how it makes the queries.
Thank you.
Maybe this is expected, maybe it isn't, but I've spent quite a while trying to figure out what is going on so I want to find out.
I have a "base" class that extends Eloquent's Model:
class InternalModel extends Model {
use Eloquence, Mappable;
protected $maps = [];
... custom method overides ...
}
Then I have multiple Entities that extend that:
class A extends InternalModel {
protected $maps = ['id' => 'BAD_ID_COL', 'data' => 'BAD_DATA_COL'];
}
class B extends InternalModel {
protected $maps = ['id' => 'DIFFERENT_BUT_STILL_BAD_ID_COL', 'user => 'BAD_USER_COL'];
}
When I:
$q = A::select(['id', 'data'])->where('id', '>', 0);
dd($q->toSql());
$q = B::select(['id', 'user'])->where('id', '>', 0);
dd($q->toSql());
I get:
"select `a`.`BAD_ID_COL`, `a`.`BAD_DATA_COL` from `a` where `BAD_ID_COL` > ?"
"select `id` from `B` where `id` = ?"
As you can see, when both queries are run against classes that inherit from InternalModel, which uses the Mappable trait, the second query does not translate the column names, leading to column not found SQL errors. Deeper investigation has shown that the reason is that both classes are using the same static $mappedAttributes
property in Mappable. I believe this is a similar issue to what is shown here: http://stackoverflow.com/questions/31629907/staticproperty-in-trait-returns-data-bound-to-the-trait-instead-of-class
Since the values of $this->maps
and static::$mappedAttributes
are the same once initialized, I can fix this issue by replacing every instance of static::$mappedAttributes
with $this->maps
. Why is static::$mappedAttributes preferred, or am I likely breaking something by changing this?
Thanks for reading.
Hello.
I've been looking at the package and I just realised that no-where in the documentation there is a requirement that we need to add a fulltext index to the columns we want to search.
Am I missing something?
Just installed this.. getting this error with my first simple query. Here is my code.
Is it expected that the Collection method keyBy() would not work with Mappable columns?
I have:
class Person extends Model
{
use Eloquence, Mappable;
protected $table = 'SLSMAN',
$primaryKey = 'SISM#',
$connection = 'ibmi',
$maps = [
'first_name' => 'SIFNAM',
'last_name' => 'SILNAM'
];
...
And:
$people = Person::get()->keyBy('first_name');
But my collection only has one item in it and the key is an empty string. Using the original field name (like SIFNAM) returns the expected collection with items keyed by first name. Is this the expected behavior for Mappable?
Thanks for reading.
I have used your eloquence search with my Laravel 5.1 application. It performing well with my requirement so thanks for the great module. But I have struggled to use the pagination with this module can you please help me to use pagination class with this?
Thanks.
When I upgrade to Laravel 5.2. I noticed a compile error in Builder.php File Sofa \ Hookable package. Stating that the implementation of the method "pluck" should be consistent with the implementation of the file "Illuminate \ Database \ Eloquent \ Builder".
I realized that at that lacked a parameter ($ key) in the method signature.
I did the manual implementation. But I wonder when we update the version of eloquence with all that it takes.
Hello there,
Probably I am doing something wrong but after upgrade from L5.0 to L5.1 I am facing this error:
ErrorException in AttributeBag.php line 74:
Argument 1 passed to Sofa\Eloquence\Metable\AttributeBag::addInstance() must be an instance of Sofa\Eloquence\Metable\Attribute, string given, called in /var/www/dltec51-teste/vendor/sofa/eloquence/src/Metable/AttributeBag.php on line 66 and defined (View: /var/www/dltec51-teste/app/Modules/Dashboard/Resources/Views/index.blade.php)
Anybody here had faced this error too?
Regards.
Alexei
Thank you for this package!
Would it be too difficult to add the Nullable stuff floating around?
I can't seem to figure out how to combine the Mappable stuff into this (so no pull request) as the $this->attributes
and even $this->getAttributes()
does not seem to be picking up the field name and it has to be the non-mapped name
Maybe I have to use some of the following?
$this->hasMapping($key)
and $this->mapAttribute($key)
Thanks,
Chris
Let's say a Match has 2 Teams. (Two BelongsTo relations to the same table)
I want to search on firstTeam.name and secondTeam.name
protected $searchableColumns = ['firstTeam.name', 'secondTeam.name'];
The resulting sql is :
SELECT *
FROM matchs
LEFT JOIN teams ON matchs.firstTeam_id = teams.id
LEFT JOIN teams ON matchs.secondTeam_id = teams.id
The search logic will be applied twice, both times on "teams.name", which is ambiguous.
The resulting sql should be :
SELECT *
FROM matchs
LEFT JOIN teams AS firstTeam ON matchs.firstTeam_id = firstTeam.id
LEFT JOIN teams AS secondTeam ON matchs.secondTeam_id = secondTeam.id
Simply set an alias to every duplicated table, using it's Laravel relation name, firstTeam and secondTeam in this case.
What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.