Eloquient with relation not working with find - eloquent

I am new to laravel. I am facing a very weird problem. I have a model comment which is related to User model in laravel.
The Relationships are defined as such
//App\User model
public function comments()
{
return $this->hasMany('App\comment');
}
And
//App\Comment model
public function User()
{
return $this->belongsTo('App\User');
}
now when i am fetching user and comment s using find and with it is returning data for all the users in the table. My code is like this: App\User::find(1)->with('comments')->get(); Can some one tell me what am doing wrong?

Try something like this
$comments=App\User::whereId(1)->comments->get();
This should load every comment associated with user with ID 1

//App\User model
public function comments() {
return $this->hasMany('App\comment','user_id','id');
}
//In your controller
use App\User;
$comment = User::where('id',2)->comments->get();
//I hope It's work for you!

Related

Create Algolia custom index magento

I need to use the event "algolia_product_index_before" and add an object "_geoloc":{ "lat":14.23890,"lng":25.234773} I have lat lng attributes added to every product. How do I go about building this observer?
If you want to add your object to Algolia, in your event observer, you can do something like this:
public function execute(Observer $observer)
{
$customData = $observer->getData('custom_data');
$customData->setData(
'_geoloc',
'{ "lat":14.23890,"lng":25.234773}'
);
return $this;
}
I hope this will help you to solve your issue
Cheers

Mass CRUD REST edit/update controller

I am trying to create a RESTful CRUD controller with a little but significant difference that might be in conflict with REST idea but anyway:
I am trying to mass edit items like so /photos/{photo}/edit where item id parameters are like /photos/0&2&7/edit
What is the proper way to establish that in Laravel 5.3?
Is there a way to use some method injections or at least to receive a collection of parameters in the controller method ?
public function edit($id) {
//.......
}
Appreciate your kind help, BR
Using Eloquent you can do whereIn, so you just need to explode the photo parameter so that all the ids are in an array:
public function edit($ids) {
$photo_ids = explode('&', $ids);
$images = Image::whereIn('id', $photo_ids)->get();
}
You can switch out statically accessing the Image model like I did in this example, you can just method inject or dependency inject the image model, let me know if you'd like assistance with dependency/method injection.
Hey i guess you are trying Model binding so you have to use like this
public function edit(Photo $photo) {
//.......
}
Your route should like this
Route::model('photos','App\Photo');
Route::resource('photos','PhotoController');
or you can try this way
your route and function like this
Route::resource('photos','PhotoController');
public function edit($id) {
$photo = Photo::findorFail($id);
}

Is splitting an index action into multiple ones a restful-friendly approach?

I need to display two different index pages to two different user groups. For example, a regular user should see one page, and a privileged user - another one. I see two ways of approaching this issue:
One index action with conditionals:
public function index()
{
// view for privileged users
if(request()->user()->hasRole('privileged')){
return view('index_privileged');
}
// view for regular users
if(request()->user()->hasRole('regular')){
return view('index_regular');
}
return redirect('/');
}
Multiple actions:
public function index_privileged()
{
return view('index_privileged');
}
public function index_regular()
{
return view('index_regular');
}
Which approach is more "restful-friendly" and generally better?
I'm a big fan of light controllers. This might be a little overboard for a simple problem but if something like this pops up again, you'd already have everything all setup.
With that said, it might be best to create a PrivilegedUser class and a RegularUser class and give them both an index method which returns their respective views. Code them both to an interface UserInterface and make sure they both implement that.
Here is what those looked like in my test.
class RegularUser implements UserInterface
{
public function index()
{
return view('index_regular');
}
}
class PrivilegedUser implements UserInterface
{
public function index()
{
return view('index_privileged');
}
}
interface UserInterface
{
public function index();
}
Then you can add a listener which should run for the event Illuminate\Auth\Events\Login. Laravel will fire this event for you automatically when someone logs in. This goes into the file EventServiceProvider.php.
protected $listen = [
'Illuminate\Auth\Events\Login' => [
'App\Listeners\AuthLoginListener',
],
];
Now you can run php artisan event:generate to generate the new listener. Here is what my listener looks like, it should work for you.
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
use Illuminate\Foundation\Application;
class AuthLoginListener
{
/**
* Create the event listener.
*
* #param Application $app
*/
public function __construct(Application $app)
{
$this->app = $app;
}
/**
* Handle the event.
*
* #param Login $event
* #return void
*/
public function handle(Login $event)
{
if ($event->user->hasRole('privileged')) {
$this->app->bind('App\Repositories\UserInterface', 'App\Repositories\PrivilegedUser');
} else if ($event->user->hasRole('regular')) {
$this->app->bind('App\Repositories\UserInterface', 'App\Repositories\RegularUser');
}
}
}
Essentially what this is doing is telling Laravel to load up a certain class based on the type of user that just logged in. The User instance is available through the Login object which was automatically passed in by Laravel.
Now that everything is setup, we barely have to do anything in our controller and if you need to do more things that are different depending on the user, just add them to the RegularUser or PrivilegedUser class. If you get more types of users, simply write a new class for them that implements the interface, add an additional else if to your AuthLoginListener and you should be good to go.
To use this, in your controller, you'd do something like the following...
// Have Laravel make our user class
$userRepository = App::make('App\Repositories\UserInterface');
return $userRepository->index()->with('someData', $data);
Or even better, inject it as a dependency.
use App\Repositories\UserInterface;
class YourController extends Controller
{
public function index(UserInterface $user)
{
return $user->index();
}
}
Edit:
I just realized I forgot the part where you wanted to return redirect('/'); if no condition was met. You could create a new class GuestUser (I know this sounds like an oxymoron) which implements UserInterface but instead of using the AuthLoginListener, I'd bind it in a service provider when Laravel boots. This way Laravel will always have something to return when it needs an implementation of UserInterface in the event it needs this class if no one is logged in.
Well, its more like a refactoring "issue" than a rest-friendly issue. Check this guideline and you can see that most of the things that makes an api friendly is concerned to the url.
But, lets answer what you are asking. The thing you wanna do is a refactoring method but it is not only the move method but something like the extract variable.
The second option would make the code more readable, either ways are right but the second is more developer friendly. It enhances the code readability from any developer. I would recommend using the second option.
Refactoring is never enough, but read something like this, it will help you a lot writing more readable codes.

Jenssegers Laravel-Mongodb return null if get by parameter

I'm new to Laravel-Mongodb, trying to get result by parameter but it's not working
Model:
use Jenssegers\Mongodb\Model as Eloquent;
class Customer extends Eloquent {
protected $connection = 'mongodb';
protected $collection = 'Customer';
}
Controller:
class AdminController extends Controller
{
public function index() {
return Customer::all();
}
public function show($id) {
return Customer::find($id);
}
}
It's alright for index() but it will return empty for show($id), it will work if using:
return Customer::find(1);
I'm not sure why it's not working with parameter, am I missing something?
You need to add one protected variable in your model like below
protected $primaryKey = “customerId”
You can add your own primary key to this variable but if you won’t add this line in model, model will by default take _id as your primary key and _id is autogenerated mongodb’s unique id.
Thats the reason why you are not able to get record by id.
1 is not a valid ObjectId. Try to find a valid ID with a tool like Robomongo or just list your customers with your index method to find out what the IDs are.
The query should look more like this:
return Customer::find("507f1f77bcf86cd799439011");
You can read more about MongoDBs ObjectId here:
https://docs.mongodb.org/manual/reference/object-id/

atk4 simple dropdown from database table

I want to populate a dropdown from a table 'accountgroups' which has 2 columns id and name. The first row of dropdown should be blank or '--Select Account Group--' when first loaded. Once the user selects the item (i.e. display field 'name' and value field 'id') I want to get id and name values when form is submited.
You'll need to create a model for your table first:
class Model_AccountGroups extends Model_Table {
public $table='accountgroups';
function init(){
parent::init();
$this->addField('name');
}
}
$form->addField('dropdown','account_id')->setModel('AccountGroups');
if($form->isSubmitted()){
$form->js()->univ()->alert('Selected ID='.$form->get('account_id'))->execute();
}
Probably (your post have an year and a half) you had resolved your issue, but I want anyway contribute with "my 2 cents" for this issue. I looked around (documentation, forums, etc) and neither found another solution to the same problem. My solution (tested and working) is this (please is is not efficient enough let me know):
>>>>>>>>>>>>>>>>>>>>> ON MODEL
class Model_Offices extends Model_Table {
public $entity_code='Offices';
function init(){
parent::init();
$this->addField('ID')->ReadOnly(True);
$this->addField('OfficeName');
}
function GetAll() {
$r=array();
$AllOffices = $this->SetModel('Offices');
foreach($AllOffices as $OneOffice) {
$r[$OneOffice['ID']]=$OneOffice['OfficeName'];
}
return $r;
}
}
>>>>>>>>>>>>>>>>>>>> ON PAGE
$m=$this->Add('Model_Offices');
$form->addField('dropdown','Office')->SetValueList($m->GetAll()) ;
Mack