Is possible in Laravel Nova 4 use a field of nested relation in search fields? - laravel

I have the following db:
Showcases (n to 1) Workers (1 to 1) Users
I need in the showcase resource section find showcase by user's name. In the Nova's documentation they explains that is possible search by related field like this:
public static $search = [
'id', 'author.name'
];
If I try 'worker.user.name' it doesn't works. Any idea?

You'll have to define it on your Laravel Model, otherwise it wont work.
use Laravel\Nova\Query\Search\SearchableRelation;
/**
* Get the searchable columns for the resource.
*
* #return array
*/
public static function searchableColumns()
{
return ['id', new SearchableRelation('author', 'name')];
}

You can use this package titasgailius/search-relations.
<?php
namespace App\Nova\Resources\OrderManagement;
use App\Nova\Resources\Resource;
use Titasgailius\SearchRelations\SearchesRelations;
class Showcase extends Resource
{
use SearchesRelations;
/**
* The relationship columns that should be searched.
*
* #var array
*/
public static $searchRelations = [
'worker.user' => ['name'],
];
/**
* Get the fields displayed by the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function fields(Request $request)
{
return [];
}
}
*Assuming you have set the belongsTo relationships properly in your models.

Related

Edit Fields Not working; not updating, and sending empty array to backend

I am using Laravel version 9.41 and Nova 4.
I can delete records, however it appears that on the frontend/JavaScript side of things my form fields are not having their contents captured and sent back to the server. My action_events table shows [ ] empty arrays as what is being sent.
I have spent a good four or five hours googling and checking that my Resources, field names etc. are all spelled correctly. I also see no error messages. Each time I get the green success message, "This has been updated!" or whatever.
use Illuminate\Http\Request;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
class Post extends Resource
{
/**
* The model the resource corresponds to.
*
* #var class-string<\App\Models\Post>
*/
public static $model = \App\Models\Post::class;
/**
* The single value that should be used to represent the resource when being displayed.
*
* #var string
*/
public static $title = 'id';
/**
* The columns that should be searched.
*
* #var array
*/
public static $search = [
'id',
'text'
];
/**
* Get the fields displayed by the resource.
*
* #param \Laravel\Nova\Http\Requests\NovaRequest $request
* #return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make('id', 'id')->sortable(),
Text::make('text', 'text')->sortable()
];
}
Someone gave me the answer elsewhere: inn my Post model, after deleting/commenting out the lines in the screenshot below: all worked fine. There was no reason to define the following properties. They are not part of any Eloquent conversion. I did not need the following (in App/Models/Post):

Laravel Nova BelongsTo Field Appending Namespace To Current Namespace

I am currently using laravel 5.8 with laravel nova.
When i use a model class inside my nova action file, like this:
Namespace App\Nova\Actions;
use App\Nova\User;
use Orlyapps\NovaBelongsToDepend\NovaBelongsToDepend;
class PlayerDD extends Action
{
public $name = 'Spelers toekennen';
/**
* Perform the action on the given models.
*
* #param \Laravel\Nova\Fields\ActionFields $fields
* #param \Illuminate\Support\Collection $models
* #return mixed
*/
public function handle()
{
}
/**
* Get the fields available on the action.
*
* #return array
*/
public function fields()
{
return [
BelongsTo::make(User::class)
];
}
}
Laravel returns the error: Class 'App\Nova\Actions\App\Nova\User' not found.
While i am using the root namespace for the User model, the namespace gets appended to the current namespace.
Is there a fix for this, and where should i look for conflicts?
Thanks in advance!
BTW, i tried this \App\Nova\User

Laravel only retrieve Model Records if they belong to authenticated user

I'm using Laravel 5.4 and have a Model called Order.
To test things I've created two users and two Orders, each user having one Order.
I've just seen that I'm able to retrieve the order of someone who is not my current user. I'm retrieving a list of user's own orders using Auth::user()->orders. But in order to show the details of a specific order I do this:
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$order = CustomerOrder::findOrFail($id)->with('products')->get();
return view('order.show')
->with('order', $order);
}
What am I missing out here? Is there a middleware or something to tell the application to only allow access to orders associated with the authenticated user?
Edit: So I've tried to do it using a Policy OrderPolicy (CRUD).
The view() fucntion of the Policy:
/**
* Determine whether the user can view the customerOrder.
*
* #param \App\User $user
* #param \App\CustomerOrder $customerOrder
* #return mixed
*/
public function view(User $user, CustomerOrder $customerOrder)
{
return $user->id === $customerOrder->user_id;
}
And I've registered it in the AuthServiceProvider.php:
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
Adress::class => AdressPolicy::class, //Doesn't work either
Order::class => OrderPolicy::class
];
I can still check the Order for another user.
You have a few options. The best option in my option is the use Policies. The documentation for this can be found here:
https://laravel.com/docs/5.4/authorization
Alternatively do could do something like:
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($id)
{
$user = request()->user();
$order = $user->orders()->with('products')->find($id)->get();
return view('order.show', compact('order'));
}
With an orders relationship function on your user model.
Updated Reply
With the policy you gave, and with your resource route, you should be able to do:
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show(CustomerOrder $order)
{
$this->authorize('view', $order);
return view('order.show', compact('order'));
}
Another way would be to use the defined relationship and tell it to only retrieve the one with id $id. Like this:
$customerOrder = auth()->user()->orders()->with('products')->find($id);
If you want to get orders which belong to authenticated user, do this:
CustomerOrder::where('user_id', auth()->user()->id)->with('products')->find($id);
Remember,
first you create policy.
second you register it.
third you use something like $this->authorize('view', $order); in your normal controller.
You are missing the third step, you can find the doc here:
[https://laravel.com/docs/5.8/authorization#authorizing-actions-using-policies][1]

How to add facet to the query (solr)

I can't add facets to the query. I try
$query = new Query;
$query->facetBuilders = [ new \eZ\Publish\API\Repository\Values\Content\Query\FacetBuilder\FieldFacetBuilder];
services:
myservice:
class: mynamespace\FacetHandler
tags:
- {name: ezpublish.search.solr.content.facet_builder_visitor}
And I have got the error "Intentionally not implemented: No visitor available for: eZ\Publish\API\Repository\Values\Content\Query\FacetBuilder\FieldFacetBuilder"
Also I have tried tag "ezpublish.search.solr.content.facet_builder_visitor.aggregate"
What I do wrong?
you are required to hand over the field you want to apply the facet on.
In your case it might look like this:
$query = new Query;
$query->facetBuilders = [ new \eZ\Publish\API\Repository\Values\Content\Query\FacetBuilder\FieldFacetBuilder(
[
'fieldPaths' => 'article/title'
]
)];
"article" is the type-identifier of the class to filter by. I have yet to try if you can actually use it without a class-limitation.
"title" defines the field-identifier to use for the facet.
You may also use regex or sort (in addition to the fieldPaths-key to filter and sort the result.
The possible values for sort are listed as constants in the FieldFacetBuilder-class
Hope this helps.
Configure your field class as below
parameters:
ezpublish.search.solr.query.content.facet_builder_visitor.field.class: Your\Bundle\Query\Content\FacetBuilderVisitor\Field
Define your service as below:
ezpublish.search.solr.query.content.facet_builder_visitor.field:
class: "%ezpublish.search.solr.query.content.facet_builder_visitor.field.class%"
tags:
- {name: ezpublish.search.solr.query.content.facet_builder_visitor}
Implement your class
<?php
/**
*
*/
namespace Your\Bundle\Query\Content\FacetBuilderVisitor;
use EzSystems\EzPlatformSolrSearchEngine\Query\FacetBuilderVisitor;
use eZ\Publish\API\Repository\Values\Content\Query\FacetBuilder;
use eZ\Publish\API\Repository\Values\Content\Search\Facet;
/**
* Visits the Field facet builder.
*/
class Field extends FacetBuilderVisitor
{
/**
* CHeck if visitor is applicable to current facet result.
*
* #param string $field
*
* #return bool
*/
public function canMap($field)
{
return $field === 'field_id';
}
/**
* Map Solr facet result back to facet objects.
*
* #param string $field
* #param array $data
*
* #return Facet
*/
public function map($field, array $data)
{
return new Facet\FieldFacet(
array(
'name' => 'field',
'entries' => $this->mapData($data),
)
);
}
/**
* Check if visitor is applicable to current facet builder.
*
* #param FacetBuilder $facetBuilder
*
* #return bool
*/
public function canVisit(FacetBuilder $facetBuilder)
{
return $facetBuilder instanceof FacetBuilder\FieldFacetBuilder;
}
/**
* Map field value to a proper Solr representation.
*
* #param FacetBuilder $facetBuilder;
*
* #return string
*/
public function visit(FacetBuilder $facetBuilder)
{
return array(
'facet.field' => 'field_id',
'f.field_id.facet.limit' => $facetBuilder->limit,
'f.field_id.facet.mincount' => $facetBuilder->minCount,
);
}
}
No more exception now ;) But does not work :'( https://doc.ez.no/display/DEVELOPER/Browsing%2C+finding%2C+viewing#Browsing,finding,viewing-PerformingaFacetedSearch

Laravel Model accessing a value of an instance of its self

I've got a model and the model its self could be linked to multiple other databases but only one at a time.
Instead of having a eloquent method for all the possible databases; it could have one that will use a variable from the self instance to choose the database and return just that.
It will save alot of work, as returning each one and testing to see if there are any results is cumbersome.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Feature extends Model
{
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'companies';
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name',
];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = [
'db_name',
'enabled',
];
/**
* Uses the its own database name to determine which input to return.
*/
public function inputs() {
// if this->hidden->db_name == 'input type 1'
// return $this->HasMany(InputType1::class);
.... and so on
} // end function inputs
}
This is definitely a strange behaviour but I think you can achieve what you are looking for like so :
//in your model
public function inputs()
{
switch ($this->attributes['db_name']) {
case : 'input type 1':
return $this->hasMany(InputType1::class);
case : //some other database name
return //another relation
}
}
Expanding on shempognon answer, what I actually got to work was
switch($this->db_name) {
case 'Input_Timesheet':
return $this->hasMany(Input_type1::class);
}

Resources