Algolia Restrict Index's data - laravel

I am trying to create a new index in Algolia which is identical with my first index but will have a different data from my first index. I want to have a contacts index for NZ and another for AU.
I used indexOnly($index_name) with a condition inside this function. But it is not working properly and I don't know if this function is what I need.
This is how I am creating it
class Contact extends Model {
use AlgoliaEloquentTrait;
protected $table = 'contacts';
public $indices = ['contacts_local'];
/** ALGOLIA SETTINGS */
public function getAlgoliaRecord()
{
return fractal()->item($this)->transformWith(new ContactTransformer)->toArray();
}
private $index_name = 'contacts_local';
public function indexOnly($index_name) {
return $this->contact_country == 'New Zealand';
}
}
I then run the reindex function.
The above method returns nothing in my contacts_local index.
Anything i'm doing wrong here?
I am using the same table in my database but the two indices will have different data depending on the country of the contact. Would this be possible in Algolia?

I'm not sure this is doable with the Algolia Laravel/Eloquent integration. What I would do instead is:
push all the records/contacts to the same (unique) index
tag the records with their associated countries (in the _tags attribute)
use Algolia's Secured API Keys to hash-generate some keys that are restricted to a specific countries using the tagFilters (https://www.algolia.com/doc/guides/search/filtering-faceting#filter-by-tag)
This will be easier and as fast as having 1 index per country.

Related

How to retrieve data with composite primary key in Laravel

I am working with four tables in Laravel and trying to display data to a view. I believe I am stuck because one of the tables has a composite primary key.
I have the following in my controller:
public function show($id)
{
//Get application for drug
$application = PharmaApplication::where('ApplNo', $id)->first();
//Return all products for application
$drugs = $application->products;
return view('profiles.drug', compact('drugs'));
}
I have the following in my PharmaApplication model:
public function products()
{
return $this->hasMany('App\PharmaProduct', 'ApplNo', 'ApplNo');
}
I have the following in my view (which I cannot complete)
#foreach ($drugs as $drug)
<li>{{$drug->Strength}}</li>
<li>{{$drug->Form}}</li>
<li>{{$drug->Form}}</li>
#endforeach
I am trying to accomplish the following:
Get the application for a drug - this part of my code works
Return an array of objects for the products (i.e. 7 products that belong to one application). I can do this but get stuck going to the next part.
Next, I have to use the array of objects and search a table with the following columns: MarketingStatusID, ApplNo, ProductNo. I know how to query this table and get one row using DB Query, but then how do I get the proper result to that query within the for loop in my view?
Finally, I use the MarketingStatusID to retrieve the MarketingStatusDescription which I will know how to do.

Laravel - Using different field names in the database (userid in a table and created_by in other)

I am trying to use a table for my Users and separate table for users' Projects in my database. However I want the names of the fields to be different for user id. What I want to take the id from the 'Users' table; and while saving the created project to the database, use that (user) id as created_by_id in Projects table.
public function store(CreateProjectRequest $request)
{
$project = new Project($request->all());
Auth::user()->projects()->save($project);
// Project::create($request->all());
return redirect('pages/home');
}
Also in Users.php, I added:
public function projects()
{
return $this->hasMany('App\Project');
}
The commented field is working on its own. However, I guess my problem arises because when I comment that line again, and add the other two lines ($project... and Auth::user... bits), I guess it is assuming I have a field in the Projects table named id.
I thought I would work around this problem with changing the primary key but I couldn't find how to take the Auth::user()->id; and make it write that value in created_by_id in a secure way. This is what I found though:
class Project extends Eloquent {
protected $primaryKey = 'created_by_id';
}
Edit: I don't think changing the primary key is my solution.
You can pass a second and third parameter to hasMany() method to specify the keys to use. Documentation
public function projects()
{
return $this->hasMany('App\Article','userid','created_by');
}

Use a different column on a many-to-many relationship in Laravel 4

I've got a situation in a project where I need to form a relationship between a primary key on one table and an indexed column (not the primary key) on another. Here's a sample of the database layout:
courses table
id
level
resources table
id
courses_resources table
course_level
resource_id
In my CourseResource model I have the following:
public function courses(){
return $this->belongsToMany('Course', 'courses_resources', 'resource_id', 'course_level');
}
Which works fine.
Then in my Course model I have:
public function resources(){
return $this->belongsToMany('CourseResource', 'course_resources', 'course_level', 'resource_id');
}
Which doesn't work. When I look at the last query performed on the database, it appears Laravel is searching the course_level column using the course's ID. That makes sense, but is there any way to use the level column for this relationship?
Eloquent BelongsToMany depends on PKs, so there is no way to do that with its methods.
You need custom relation object for this, that will check for given field, instead of primary key.
A quick and hacky solution would be this:
// Course model
public function getKey()
{
$relation = array_get(debug_backtrace(1, 2), '1.object', null);
if (method_exists($relation, 'getForeignKey')
&& $relation->getForeignKey() == 'courses_resources.course_level')
{
return $this->getAttribute('level');
}
return parent::getKey();
}
However if you would like to use it in production, do some extensive testing first.

eloquent return two columns all records

I'm sure this is very simple - I just need two columns from a country database to populate a <select>
Looking at this URL I came up with the code below, but this seems to return an object for each record
http://laravel.com/api/class-Illuminate.Database.Eloquent.Model.html#_all
class countries extends Eloquent
{
}
public static function getCountrySelect()
{
return countries::all(array("name","iso_3166_2"));
}
If you want to populate custom field from database use this:->
countries::lists('name','iso_3166_2');
i.e
countries::lists('coulmnname1','coulmnname2');
and if you want to get suppose first 10 entries for that model use this:
countries::take(10)->get();

Laravel 4: Keeping a table Relationship when reducing structure into several tables

History:
DB: Tables clients and titles
A Client can have many titles but a title can only have one client. So i will use a simple one-to-many relationship as illustrated below:
Client Model
class Client extends Eloquent {
public function titles(){
return $this->hasMany('titles');
}
}
Then i simply use the following to get the requested data for the selected title
$clientTitles = Client::find(1)->titles;
All in all this should list all client associated titles.
My question really comes to this as i am looking to split my data within my titles table into smaller tables as i also use some aspects of the titles data somewhere within the system and do not need to get all of the title details every time.
So i would have another three tables related to the titles data table
Titles, Title_Artwork, Title_Details, Titles_List
Now if i use the same as above i will get all the data within the titles table, but not the other three. So how can i then update my relationship to then scrape the other three title tables so when i need to, i can get all the data, rather.
Or is there another way to do this or NO keep to what i have done an just limit the call to the fields i require?
From what I understood, And lets assume that your Titles model is some what like-
class Titles extends Eloquent{
public function titleartwork(){
return ..
}
public function titledetails(){
return ..
}
public function titlelist(){
return ..
}
}
And your client model is-
class Client extends Eloquent {
public function titles(){
return $this->hasMany('titles');
}
}
So in order to get the data of any of these tables Title_Artwork, Title_Details, Titles_List
you can do this
$clientTitles = Client::with('Titles','Titles.titleartwork','Titles.titlelist')->where('id','=',1)->get();
In terms of Laravel it is known as Eager Loading, to know more you can check the doc
It will also work with multiple nesting, I mean if your Title_Artwork also contains relationship like-
class TitleArtwork extends Eloquent{
public function sometable(){
return ..;
}
}
Then you can get the data of sometable using
$clientTitles = Client::with('Titles','Titles.titleartwork.sometable','Titles.titlelist')->where('id','=',1)->get();

Resources