I am using https://github.com/mitulgolakiya/laravel-api-generator
I would like to get data from another model. When inserting a post pick the category data.
PostController.php
class PostController extends AppBaseController
{
/** #var PostRepository */
private $postRepository;
/** #var CategoriesRepository */
private $categoriesRepository;
function __construct(PostRepository $postRepo, CategoriesRepository $categoriesRepo)
{
$this->postRepository = $postRepo;
$this->categoriesRepository = $categoriesRepo;
}
/**
* Display a listing of the Post.
*
* #return Response
*/
public function index()
{
$posts = $this->postRepository->paginate(10);
$categories = $this->categoriesRepository->all('id', 'desc')->get();
return view('posts.index')
->with('posts', $posts)
->with('categories', $categories);
}
fields.blade.php
{!! Form::select('category_id', Categories::lists('name', 'id'), ['class' => 'form-control']) !!}
How can I do this? Thank you!
You should make the list in controller and pass it to the view.
public function index()
{
$posts = $this->postRepository->paginate(10);
$categories = $this->categoriesRepository->all('id', 'desc')->get();
$categoryList = [ '' => '--select--' ] + $categories->lists('name', 'id');
return view('posts.index')
->with('posts', $posts)
->with('categories', $categories)
->with('categoryList', $categoryList);
}
And use this variable to generate the select.
{!! Form::select('category_id', $categoryList, ['class' => 'form-control']) !!}
I think you should use ViewComposers and pass category list array in fields.blade.php. so it will not affect directly your templates or generator.
Whenever you have a requirement where you always have to pass fields of another model in any view, I think you should use view composer.
Related
Im try to create a simple CRUD App in Laravel + Vue.JS (Vuex also)
And I have small problem
What is the problem actually
I have a table 'categories'
Structure of this table u can see on screenshot
And i have created 2 test rows
u can see on screenshot
How can I insert a title instead of a value parent_id
If parent_id has value like someone ids
Im try v-for in Vue Componetn and v-if
But i dont have any results
This is my code:
<tr v-for="(category, $index) in categories" :key="category.id">
<td>{{$index + 1}}</td>
<td>{{category.title}}</td>
<td v-if="category.parent_id === null">Category</td>
<td v-else>SubCategory</td>
<td>{{category.created_at | moment("DD, MMMM, YYYY")}}</td>
<td></td>
</tr>
This is my data what im get from Controller
Anyway thanks for help
This is code of controller
public function index()
{
$result = ['success' => true];
$category = Category::paginate(15);
$result['category'] = $category->items();
$result['pagination']['currentPage'] = $category->currentPage();
$result['pagination']['total'] = $category->total();
$result['pagination']['perPage'] = $category->perPage();
return response()->json($result, 200);
}
And here is how I want it to be
I think render function adn array processing must be at the Vue Component
This is my Category model code
public function products()
{
return $this->hasMany('App/Products');
}
public function parent()
{
return $this->hasOne(Category::class,'id','parent_id');
}
Solution will be to define relation hasOne like
public function parent()
{
return $this->hasOne(Category::class,'id','parent_id');
}
And then you can define resource, where you can claim parent's title using defined relation like below
$this->parent->title
Create you resource using command
php artisan make:resource CategoryResource
Then in your controller you should use resource
use App\Http\Resources\CategoryResource;
and within controller's action provide response like
$categories = Category::paginate(15);
return CategoryResource::collection($results); // instead of response()->json($categories , 200);
And example how your resource should look like
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class CategoryResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'parent_id' => $this->parent_id,
'parent_title' => $this->parent->title,
...
];
}
}
Info about resources you can find https://laravel.com/docs/5.8/eloquent-resources
I've gone through quite a few tutorials, and I'm starting to get there with Laravel, however, one thing I've somehow missed in these tutorials/failed to spot, is how to accomplish "selective updating", apologies if that's the wrong wording, however this is my issue.
I have the user model, this contains multiple custom fields on top of the auth fields added by Laravel, the custom fields are:
ConsiderForAccommodation
Attending
I currently have a form in a view that allows the user to set choose whether they would like to be considered for accommodation, this works as follows:
User Model
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'considerForAccommodation'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
User Controller
public function update(Request $request)
{
// Update the given user
$user = auth()->user();
// If the value is null then it's false.
$user->ConsiderForAccommodation = $request->input('ConsiderForAccommodation') != null;
$user->save();
return redirect('/accommodation');
}
Accommodation View (form)
#section('content')
<h1>Accomodation</h1>
<p>This is the accomodation page.</p>
{!! Form::open(['action' => ['UserController#update', Auth::id()], 'method' => 'POST']) !!}
<div class="form-group">
{{Form::label('ConsiderForAccommodation', 'Consider Me For Accommodation')}}
{{Form::checkbox('ConsiderForAccommodation', null, Auth::user()->ConsiderForAccommodation)}}
</div>
{!! Form::token() !!}
{{Form::hidden('_method', 'PUT')}}
{{Form::submit('Submit', ['class' => 'btn btn-primary'])}}
{!! Form::close() !!}
#endsection
Route
Route::get('/', 'PagesController#index');
Route::get('/accommodation', 'PagesController#accommodation');
Route::get('/registry', 'PagesController#registry');
Route::get('/rsvp', 'PagesController#rsvp');
Route::get('/schedule', 'PagesController#schedule');
Route::get('/travel', 'PagesController#travel');
Route::resource('user', 'UserController');
Auth::routes();
As I mentioned, this imlementation works as intended. Now, the issue is I have another seperate form (within a different view), that I would like to contain a form that only updates the "Attending" value against the model. How do I handle this in Laravel?
Do I have to create a seperate controller for each property I wish to update seperatly from the others, or am I looking at this wrong entirely and there's an easy way of doing it?
Any help would be appreciated.
There are many possibilities how to solve this problem. One of them is to create one route that also has a parameter
Route::put('/users/set-parameter/{param}', 'UserController#setParameter');
Then in controller you can set different parameters in single method:
public function setParameter(Request $request, string $param)
{
$user = auth()->user();
$user->{$param} = $request->input($param) != null;
$user->save();
return redirect('/accommodation');
}
Keep in mind that sometimes it is not the best way to handle that. There are pros and cons as almost always.
I'm working with a view that at first displays all products, and on the sidebar, users can see a list of categories. My aim is when users press on any categories, it will display products of that category only. However, since there are 2 controllers is interacting with this view and send the same data, one is not running(CategoriesController). It does not show any error, just when I click on the link of each of the categories, it does not reload the page.
Here is my ProductsController:
class ProductsController extends Controller
{
// display all products and categories
public function index() {
$products = Product::all();
$categories = Category::all();
return view('frontend.product', compact('products','categories'));
}
And my CategoriesController:
class CategoriesController extends Controller
{
public function showProducts($category_id) {
$products = Category::find($category_id)->products;
return view('frontend.product', compact('products'));
}
Here is my view:
// Products part
#foreach($products as $product)
{{ $product->name }}
#endforeach
//Categories part
#foreach($categories as $category)
{{ $category->name }}
#endforeach
And route:
Route::get('/products', [ 'as' => 'products', 'uses' => 'frontend\ProductsController#index']);
Route::get('/categories/{category_id}', ['as' => 'categories', 'uses' => 'backend\CategoriesController#showProducts']);
Just include all of the categories in your showProducts function, and omit the current category:
public function showProducts($category_id)
{
$categories = Category::whereNotIn('id', $category_id)->get();
$products = Category::find($category_id)->products;
return view('frontend.product', compact('products', 'categories'));
}
Now there will be no discrepancies between the variables that are being used.
If I have not misunderstood, I thought you can use #inject in blade. For example:
namespace App\Presenters;
use App\User;
class UserPresenter
{
/**
* 是否顯示email
* #param User $user
* #return string
*/
public function showEmail(User $user)
{
if ($user->show_email == 'Y')
return '<h2>' . $user->email . '</h2>';
else
return '';
}
}
and
<div>
#inject('userPresenter', 'MyBlog\Presenters\UserPresenter')
#foreach($users as $user)
<div>
{!! $userPresenter->showEmail($user) !!}
</div>
</div>
I'm creating a news feed kind of thing where users can post anything and the post will have comments also. I'm able to create the newsfeed and the comment section, but my real problem is I'm not able to show the comments which belongs to the post. Right now all the comments are displayed under every news feed. Though I've declared the eloquent relationship between feed and comment but still I'm not able to save the feed_id in comment table.
This is my FeedsController:-
<?php namespace App\Http\Controllers;
use Request;
use Auth;
use Sentinel;
use App\Feed;
use App\Http\Requests;
use App\Blog;
use App\Http\Controllers\Controller;
use App\Comment;
class FeedsController extends Controller
{
public function index() {
$comments = Comment::latest()->get();
$feeds = Feed::where('user_id', Sentinel::getUser()->id)->latest()->get();
$blogs = Blog::latest()->simplePaginate(5);
$blogs->setPath('blog');
return view('action.index')->with('feeds', $feeds)->with('comments', $comments)->with('blogs', $blogs);
}
public function store(Requests\CreateFeedRequest $request){
$requet = $request->all();
$request['user_id'] = Sentinel::getuser()->id;
Feed::create($request->all());
return redirect('home');
}
public function storecomment(Requests\CommentRequest $request, Feed $feed)
{
$comment = new Comment;
$comment->user_id =Sentinel::getuser()->id;
$comment->feed_id = $request->feed_id;
$comment->comment = $request->comment;
$comment->save();
return redirect('home');
}
}
This is the models:
Comment model
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
protected $fillable = [
'comment',
'user_id',
'feed_id'
];
public function feed()
{
return $this->belongsTo('App\Feed');
}
public function user()
{
return $this->belongsTo('App\User');
}
}
Feed model:
use Illuminate\Database\Eloquent\Model;
class Feed extends Model
{
protected $fillable = [
'feed_id',
'user_id',
'feed_content'
];
public function user()
{
return $this->belongsTo('App\User');
}
public function comment()
{
return $this->hasMany('App\Comment');
}
}
User model:-
<?php namespace App;
use Cartalyst\Sentinel\Users\EloquentUser;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends EloquentUser {
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes to be fillable from the model.
*
* A dirty hack to allow fields to be fillable by calling empty fillable array
*
* #var array
*/
protected $fillable = [];
protected $guarded = ['id'];
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = ['password', 'remember_token'];
/**
* To allow soft deletes
*/
use SoftDeletes;
protected $dates = ['deleted_at'];
public function feeds()
{
return $this->hasMany('App\Feed');
}
public function comment()
{
return $this->hasMany('App\Comment');
}
}
This is my feed.blade.php where I'm displaying the feeds output and commnets
#foreach($feeds as $feed)
<article class="media">
<div class="well">
<div class="pull-left">
<img class="profile" src="{{ URL::to('/uploads/users/'.$feed->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
<strong>{{ $feed->user->first_name }}
{{ $feed->user->last_name }}
<small> posted </small>
</strong>
{{ $feed->created_at->diffForHumans() }}<br><hr>
{{ $feed->feed_content }}
<hr>
{!! Form::open(['url' => 'home/{storecomment}']) !!}
<div class="form-group">
{!! Form::text('comment', null, ['class'=>'form-control', 'rows'=>3, 'placeholder'=>"Comment"]) !!}
</div>
<div class="form-group feed_post_submit">
{!! Form::submit('Comment', ['class' => 'btn btn-default btn-xs']) !!}
</div>
{!! Form::close() !!}
#foreach($comments as $comment)
<div class="pull-left">
<img class="profile" src="{{ URL::to('/uploads/users/'. $comment->user->pic) }}" class="img-responsive" alt="Image" style="width:48px;height:48px;padding-right : 10px;padding-bottom: 5px;">
</div>
{{ $comment->user->first_name }}
{{ $comment->created_at->diffForHumans() }}
{{ $comment->comment }}<hr>
#endforeach
</div>
</article>
#endforeach
Can anyone tell me how to store the feed_id into comment table and displaying the comments according to the feed. Thank You. I'm using Laravel 5.1
Based on our lengthy convo -
To save the feed_id (which is our foreign key for future relationships), you need to set/send the feed_id in your POST request. Laravel is not magic and won't know this automatically. You can do this by adding a hidden input, like so:
<input type="hidden" name="feed_id" value="{{ $feed->feed_id }}" />
In your FeedController, change your index to this:
public function index() {
// $comments = Comment::latest()->get(); remove this
// notice the "with" below. I'm eager loading in relations here
$feeds = Feed::with('comments', 'user')->where('user_id', Sentinel::getUser()->id)->latest()->get();
$blogs = Blog::latest()->simplePaginate(5);
$blogs->setPath('blog');
return view('action.index', compact('feeds', 'blogs'));
}
Feed Model should have the correct relationships, as below:
class Feed extends Model
{
protected $fillable = [
'feed_id',
'user_id',
'feed_content'
];
public function user()
{
return $this->belongsTo('App\User', 'id', 'user_id');
}
public function comments()
{
return $this->hasMany('App\Comment', 'feed_id', 'feed_id');
}
}
Comment Model should have the correct relationships, as below:
class Comment extends Model
{
protected $fillable = [
'comment',
'user_id',
'feed_id'
];
public function feed()
{
return $this->belongsTo('App\Feed');
}
public function user()
{
return $this->hasOne('App\User', 'id', 'user_id');
}
}
Now you should be able to run your foreach as you currently have it.
I have created registration form using Laravel, Form is working well, Validations are also working well but without validation error, when I try to save data, it redirects to "Whoops, looks like something went wrong." can someone please help me to find this error. thank you.
Form:
{{ Form::open(array('url'=>"create-account")) }}
<p>
{{ Form::text('user_name', '', array('placeholder'=>"User Name")) }}
#if($errors->has('user_name'))
<label> {{ $errors->first('user_name') }} </label>
#endif
</p>
<p>
{{ Form::text('user_email', '', array('placeholder'=>"User Email")) }}
#if($errors->has('user_email'))
{{ $errors->first('user_email') }}
#endif
</p>
<p>
{{ Form::password('user_password', array('placeholder'=>"User Password")) }}
#if($errors->has('user_password'))
{{ $errors->first('user_password') }}
#endif
</p>
<p>{{ Form::submit('Register') }}</p>
{{ Form::close() }}
And Controller has this code:
class StaffController extends BaseController {
public function getAccount() {
return View::make('staff.account');
}
public function postAccount() {
$input = Input::all();
$rules = array(
'user_name' => 'required|min:3|max:20|unique:users',
'user_email' => 'required|email|max:50|unique:users',
'user_password' => 'required|min:5'
);
$validate = Validator::make($input, $rules);
if ($validate->fails()) {
return Redirect::to('create-account')
->withErrors($validate);
} else {
$user = new User();
$user->user_name = $input['user_name'];
$user->user_email = $input['user_email'];
$user->user_password = Hash::make($input['user_password']);
$user->save();
return Redirect::to('login')
->with('global', 'Your account has been created, please login');
}
}
}
Model:
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
//protected $hidden = array('password', 'remember_token');
protected $hidden = array('user_password');
}
DB table has fields:
Table name: users
Fields:
user_id int(11)
user_name varchar(20)
user_email varchar(50)
user_password varchar(60)
status
Routes:
Route::get('/','HomeController#getIndex');
Route::get('login','HomeController#getIndex');
Route::post('login','HomeController#postLogin');
Route::get('create-account', 'StaffController#getAccount');
Route::post('create-account', 'StaffController#postAccount');