I have many to many relationship between UserProfile model and UserTv model. Here are the tables.
user_profiles
id user_id username
1 1 AuthUser
tv
id name
1 Action
2 Drama
3 Comedy
4 manually added some genre from input from authenticated user
user_tv
id user_id tv_id
1 1 2
1 1 4
For example, these first three ids in tv table (Action, Drama, Comedy) are inserted through seeders and this fourth id is inserted manually through input text from form by that user who is authenticated. And there lies the my problem. I want that those values that are manually added through input in form to only be able to see that user that inserted those values, and all other users can't. But also I want all users to remain to see those first three values that are generated through seeder. Currently everything works so that all users can see everything. Any help is appreciated. Here is my code.
UserProfile.php
<?php
namespace App;
use App\User;
use Illuminate\Support\Facades\App;
use Illuminate\Database\Eloquent\Model;
class UserProfile extends Model
{
protected $fillable = [
'user_id',
'username',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function tvs()
{
return $this->belongsToMany(UserTv::class, 'user_tv', 'user_id', 'tv_id');
}
}
UserTv.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class UserTv extends Model
{
protected $table = 'tv';
protected $fillable = [
'name'
];
public function userProfiles()
{
return $this->belongsToMany(UserProfile::class, 'user_tv', 'tv_id', 'user_id');
}
}
web.php
Route::get('profile/{profile}', 'UserProfileController#showProfile')->name('profile.show');
Route::patch('profile/update-tv-options', 'TvController#updateTvOptions')->name('profile.update.tv.options');
Route::post('profile/insert-tv-options', 'TvController#insertTvOptions')->name('profile.insert.tv.options');
TvController.php
<?php
namespace App\Http\Controllers;
use App\UserTv;
use App\UserProfile;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests\InsertTvOptionsRequest;
use App\Http\Requests\UpdateTvOptionsRequest;
class TvController extends Controller
{
public function updateTvOptions(UpdateTvOptionsRequest $request)
{
$user = Auth::user();
$userProfile = UserProfile::where('user_id', Auth::id())->first();
$userProfile->update($request->all());
$data = $request->get('tvsOptions', '[]');
$userProfile->tvs()->sync($data);
return redirect()->route('profile.show', [$user->username]);
}
public function insertTvOptions(InsertTvOptionsRequest $request)
{
$user = Auth::user();
$tv = UserTv::create($request->all());
return redirect()->route('profile.show', [$user->username]);
}
}
UserProfileController.php
<?php
namespace App\Http\Controllers;
use App\User;
use App\UserTv;
use App\UserProfile;
class UserProfileController extends Controller
{
public function showProfile($username, Request $request)
{
$profileId = User::getIdFromUsername($username);
$userForShowProfile = User::with('userProfile')->where('id', $profileId)->firstOrFail();
$tvsOptions = UserTv::get();
$userTvsOptions = UserProfile::findOrFail($profileId)->tvs()->get();
return view('profile.show', compact('userForShowProfile', 'tvsOptions', 'userTvsOptions'));
}
}
show.blade.php
<section data-edit="movies" class="editMovies">
<h3 class="textBold">Film</h3>
<form action="{{ route('profile.update.tv.options') }}" method="POST" class="flex">
#method('PATCH')
#csrf
<div class="form-group flex">
#isset($tvsOptions, $userTvsOptions)
#foreach($tvsOptions as $option)
<div class="interestedIn">
<input type="checkbox" name="tvsOptions[]" value="{{ $option->id }}" {{ $userTvsOptions->contains('id', $option->id)? 'checked': ''}}>
<label for="">{{ $option->name }}</label>
</div>
#endforeach
#endisset
</div>
<div class="form-group">
<label for="" class="textBold">Button FOR CHECKBOX</label>
<input type="submit" class="form-control" name="submit" value="BUTTON">
</div>
</form>
<form action="{{ route('profile.insert.tv.options') }}" method="POST" class="flex">
#csrf
<div class="form-group mt-5">
<input type="text" name="name" placeholder="INSERT NEW MOVIE GENRE">
</div>
<div class="form-group">
<label for="" class="textBold">Button FOR INSERT!!!</label>
<input type="submit" class="form-control" name="submit" value="BUTTON">
</div>
</form>
</section>
And I want to contain first three options for all users and that fourth option for only this user that inserted that.
Something like this?
$defaultTvsOptions = UserTv::whereIn('name', ['Action', 'Drama', 'Comedy'])->get(); // return only action, drama and comedy. you can use ids.
$userTvsOptions = UserProfile::findOrFail($profileId)->tvs;
$tvsOptions = $defaultTvsOptions->merge($userTvsOptions); // merge default and logged user tvs options
To make it more maintainable, you could use configs in your root directory of project.
$defaultTvsOptions = UserTv::whereIn('name', config('config name where return the array'));
Hope it helps you.
Hey As you Have a pivot table You can pull the data Like This:
Userprofile model
public function tv() {
return $this->hasManyThrough(
'Tv class ',
'user_tv class',
'user_id',
'id',
'user_id',
'tv_id'
);
}
UserController
$data = UserProfile::with('tv')
->where(condition)
->get();
Related
At the moment I am working with Laravel. I am trying to insert data into a database. It is not user data, but product data. Costumers have to be able to insert a title, description and price of a product into the database.
I have looked at the laravel website, however, I was unable to find anything. There are some people with the same question as mine on StackOverflow. However, the answers that were given to them do not work for me.
My controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ProductsController extends Controller
{
public function insertform(){
return view('home');
}
public function insert(Request $request){
$productname = $request->input('title');
$description = $request->input('description');
$price = $request->input('price');
$data=array('title'=>$productname,"description"=>$description,"price"=>$price);
DB::table('products')->insert($data);
echo "Record inserted successfully.<br/>";
echo 'Click Here to go back.';
}
}
My view:
#section('content')
<h1>Add your new items here:</h1>
<form method="get">
<div class="title">
<div class="title">
<span class="input-group-text" id="title">Title</span>
</div>
<input type="text" name="title" class="form-control" aria-label="title" aria-describedby="inputGroup-sizing-default">
</div>
<br>
<br>
<div class="description">
<div class="description">
<span class="input-group-text" id="description">Description</span>
</div>
<input type="text" name="description" class="form-control" aria-label="description" aria-describedby="inputGroup-sizing-default">
</div>
<br>
<br>
<div class="price">
<div class="price">
<span class="input-group-text" id="price">Price</span>
</div>
<input type="text" name="price" class="form-control" aria-label="price" aria-describedby="inputGroup-sizing-default">
</div>
<br>
<br>
<div class="form-group">
<label for="exampleFormControlFile1">Insert Image</label>
<input type="file" class="form-control-file" id="exampleFormControlFile1">
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
#endsection
My web.php:
<?php
Route::get('/', function () {
return view('welcome');
});
Route::get('insert','ProductsController#insertform');
Route::post('create','ProductsController#insert');
Auth::routes();
Route::get('/home', 'HomeController#index')->name('home');
My database structure:
The home and welcome, along with some code in the web.php, has been made by authentication.
Hopefuly you guys can help me out. I want to make sure that the product data is inserted into the database.
Don't use DB class. Instead create a model called Product and use model function to create or update data into table.
php artisan make:model Product
$product= Product::create([
'name' => $request->name, # declared as fillable on Product model
'description' => $request->description,
...
]);
Convert the route of /insert into POST and add csrf field in your form
#csrf
OR
<input type="hidden" name="_token" value="{{csrf_token()}}">
On your controller validation of input in insert function.
Also take a look at these -
https://laravel.com/docs/5.8/eloquent#defining-models
Laravel Validation Rules
or https://laravel.com/docs/5.8/validation#quick-writing-the-validation-logic
In your web.php, Add route names
Route::get('insert','ProductsController#insertform')->name('product.create');
Route::post('create','ProductsController#insert')->name('product.store');
In your view, change method to post and add action attribute and csrf field.
<form action="{{ route('product.store') }}" method="post">
#csrf
In Controller
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
class ProductsController extends Controller
{
public function insertform(){
return view('home');
}
public function insert(Request $request){
$productname = $request->input('title');
$description = $request->input('description');
$price = $request->input('price');
$data = array(
"title" => $productname,
"description" => $description,
"price" => $price
);
DB::table('products')->insert($data);
echo "Record inserted successfully.<br/>";
echo 'Click Here to go back.';
}
}
Alternate you can directly add action without route name
<form action="/create" method="post">
#csrf
In laravel 5.6 i can show you how to insert the data and display the data to the index page
so first of all i can code my route
in here we can use 2 routes
first is index page route
second is store and in store controller you can display your stored data.
Route::get('/FAQ_page', 'SettingController#FAQ_page')->name('FAQ_page');
Route::get('/FAQ_page/create', 'SettingController#FAQ_page_create')->name('FAQ_page.create');
Route::post('/FAQ_page/store', 'SettingController#FAQ_pagestore');
now make a database and connect to your module
this is your module
namespace App;
use Illuminate\Database\Eloquent\Model;
class FAQpage extends Model
{
protected $table = 'p66_FAQ_page';
public $timestamps = false;
protected $primaryKey = 'fid';
}
now make your controller like this
public function FAQ_page()
{
$data = FAQpage::get();
return view('SuperAdmin.settings.FAQ_page', compact('data'));
}
public function FAQ_page_create()
{
return view('SuperAdmin.settings.FAQ_page_create');
}
public function FAQ_pagestore(Request $request)
{
request()->validate([
'FAQ_question'=> 'required',
'FAQ_answer'=> 'required',
'Sort_order'=> 'required|max:4',
'FAQ_departments'=> 'required',
]);
$data = new FAQpage();
$data->FAQ_question = $request->get('FAQ_question');
$data->FAQ_answer = $request->get('FAQ_answer');
$data->Sort_order = $request->get('Sort_order');
$data->FAQ_departments = $request->get('FAQ_departments');
$data->Created_date = Carbon::now();
$data->save();
return redirect('/SuperAdmin/FAQ_page');
}
thank you
I currently have an application that can have a modifier with many options. An example use case is a modifier of Toppings with options of cheese, lettuce, salt, and pepper. A modifier can have 1 --> N options.
I want to have a form that displays the Modifier name and also allows the ability to edit/delete Option records at same time. I want to embed this in my current form for adding/editing modifiers.
Is there a simple way to do this so I can have just one Modifier resource controller that also manages Options?
web.php
Route::resource('modifiers', 'ModifierController')->middleware('auth');
Controller:
namespace App\Http\Controllers;
use App\Modifier;
use Illuminate\Http\Request;
class ModifierController extends Controller
{
public function create()
{
$data = ['action' => route('modifiers.store'),'method' => 'POST', 'modifier' => new Modifier()];
return view('modifiers.form',$data);
}
public function store(Request $request)
{
$modifier = new Modifier($request->all());
$this->do_validate($request);
$modifier->save();
return redirect(route('modifiers.index'));
}
}
views/modifiers/form.blade.php
#extends('layouts.layout-2')
#section('content')
<div class="container">
<div class="row justify-content-center">
#include ('layouts.errors')
<div class="col-md-12">
{!! Form::open(['url' => $action, 'method' => 'post', 'class' => 'form', 'id' => 'form'])!!}
#csrf
#method($method)
<div class="form-group">
<label for="name">{{ __('modifiers.name')}}</label>
<input type="text" class="form-control" id="name" name="name" value = "{{old('name',$modifier->name)}}">
</div>
<button id="btnSubmit" class="btn btn-primary">{{ __('common.submit') }}</button>
{!! Form::close() !!}
</div>
</div>
</div>
#endsection
Models:
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Modifier extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
public function options()
{
return $this->hasMany('App\Option');
}
}
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Option extends Model
{
use SoftDeletes;
protected $guarded = ['id'];
public function modifier()
{
return $this->belongsTo('App\Modifier');
}
}
I think you can use a select element:
<select name="options[]" id="options" class="form-control">
#foreach($options as $option)
<option value="{{ $option->id }}" {{ $modifier->options->contains('id', $option->id) ? 'selected' : '' }}>{{ $option->name }}</option>
#endforeach
</select>
Hope it helps.
Then, within some controller:
public function update(Request $request, $id)
{
$modifier = Modifier::find($id);
$modifier->options()->sync($request->input('options'));
// Do whatever more you want to do
}
I have a search form to list properties/ads through certain criteria. I am trying to fetch all properties based on offer or demand, depending on what is clicked in the form. I have three tables
properties (id, price, location)
properties_categories (property_id, category_id)
categories (id, category, priority)
In the row category in the categories table, there are two values, offer, and demand. With the current code when I select offer or demand and click submit I get [] empty array. Any help is appreciated. Here is my code:
Category.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Category extends Model
{
public $timestamps = false;
public function property()
{
return $this->belongsToMany(Property::class);
}
}
Property.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Property extends Model
{
protected $guarded = ['id'];
public function category()
{
return $this->belongsToMany(Category::class, 'properties_categories')->orderBy('priority', 'asc');
}
}
CategoryController.php
<?php
namespace App\Http\Controllers;
use App\Category;
use App\Http\Controllers\Controller;
use App\Property;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redirect;
class CategoryController extends Controller
{
public function index()
{
return view('categories.search', compact('data'));
}
public function search($propertyBidAsk, $propertyType, $propertyPayment, $city, $price, $quadrature, Request $request, Property $property)
{
$category = $property->category;
if (!empty($request->propertyBidAsk)) {
return $property->category()->where('category', $request->propertyBidAsk)->get();
}
$results = $property;
return view('categories.search', compact('category', 'results'));
}
}
search.blade.php
<div>
#if(isset($results))
<table class="table">
<thead>
<th>Property Bid Ask</th>
</thead>
<tbody>
#foreach ($results as $result)
<tr>
<td>{{ $result->category[0]->category }}</td>
</tr>
#endforeach
</tbody>
</table>
#endif
</div>
<form id="searchForm" method="GET" action="/search">
<div class="col-md-4 mb-6">
<h5>Payment</h4>
<div class="d-block my-3">
<div class="custom-control custom-radio">
<input id="offer" name="propertyBidAsk" value="offer" type="radio" class="custom-control-input">
<label class="custom-control-label" for="offer">Offer</label>
</div>
<div class="custom-control custom-radio">
<input id="demand" name="propertyBidAsk" value="demand" type="radio" class="custom-control-input">
<label class="custom-control-label" for="demand">Demand</label>
</div>
</div>
</div>
<button class="btn btn-primary btn-lg btn-block" type="submit">Search</button>
</form>
web.php
Route::get('/search', 'CategoryController#index');
Route::get('/search/{propertyBidAsk}/{propertyPayment}/{propertyType}/
{city}/{price}/{quadrature}', 'CategoryController#search');
Use different route names and remove route params like the below code,
Route::get('/search-data', 'CategoryController#search');
Also, remove parameters from the search action and use request() in your search function.
Right so im trying to make a website where a registered user can create a post. The issue i am having rigt now is getting the post to be added to the the database. It should work but im getting an error.
The error:
Call to a member function posts() on null
The error points to my post controller class
<?php
use App\Post;
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class postController extends Controller
{
public function postCreatePost(Request $request){
$post = new Post();
$post->body = $request['body'];
$request->user()->posts($post); //points here
return redirect()->route('dashboard');
}
}
This is my post migration up method:
public function up()
{
Schema::create('posts', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->text('body');
$table->integer('user_id');
});
}
Post model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
public function user(){
return $this->belongsTo['App\User'];
}
}
User model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable;
class User extends Model implements Authenticatable
{
use \Illuminate\Auth\Authenticatable;
public function posts(){
return $this->hasMany('App\Post');
}
}
The section the user types in:
<section class="row new-post">
<div class="col-md-6 col-md-offset-3">
<form action="{{ route('postcreate') }}" method="post">
<div class="form-group">
<textarea class="form-control" name="body" rows="5" placeholder="your post"></textarea>
</div>
<button type="submit" class="btn btn-primary">Create post</button>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
</div>
</section>
The problem is that on your controller you do:
$request->user()->posts($post); //points here
You are considering that user() will always return something.
If your route isn't guarded by the auth middleware, $request->user() may return null if there's no authenticated user.
So you have two options: Or you add the auth middleware, or you put an if on your code:
if ($request->user()) {
$request->user()->posts($post);
}
However, this will fix the error but it won't create a post
public function postCreatePost(Request $request){
$post = new Post();
$post->body = $request['body'];
$request->user()->posts($post); // This call isn't valid.
return redirect()->route('dashboard');
}
The right way to do is:
public function postCreatePost(Request $request){
$request->user()->posts()->create([
'body' => $request->body
// Here I'm assumming that the only field is the `body`,
// but you may need other fields if they exists.
// the `user_id` field will be automatically filled.
];
return redirect()->route('dashboard');
}
I am trying to add a record to a database utilizing a resource controller, however, I'm getting MethodNotAllowedHttpException error. I'm using a pivot table. I have gone through several similar questions like a link! but none seem to answer me. This is my code:
Routes.php
Route::group(['prefix' => 'user'], function () {
Route::resource('categories', 'User\CategoriesController');
});
CategoriesController.php
<?php
namespace App\Http\Controllers\User;
use Session;
use Sentinel;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Models\Sections;
use App\Models\Categories;
use App\Models\Users;
use App\Models\CategorieUser;
class CategoriesController extends Controller
{
public function __construct()
{
$this->middleware('sentinel.auth');
}
public function index()
{
$categories = Categories::all();
return view('user.categories.index', ['categories' => $categories]);
}
public function create()
{
$sections = sections::all();
return view('user.categories.create', ['sections' => $sections]);
}
public function store(Request $request)
{
// records in table categories
$categories = new Categories();
$categories->name = $request->name;
$categories->sections_id = $request->sections_id;
$categories->save();
// records in pivot table users_categories
$user = Sentinel::getUser()->id;
$users_categories = new CategorieUser();
$users_categories->user_id = $user;
$users_categories->categorie_id = $categories->id;
$users_categories->save();
return redirect()->route('categories.index');
}
}
This is the form:
<form action="store" method="POST">
<div class="form-group">
<label for="section">Choose section:</label>
<select class="form-control" name="sections_id">
#foreach($sections as $section)
<option value="{{ $section->id }}">{{ $section->name }}</option>
#endforeach
</select>
</div>
<div class="form-group">
<label for="name">Category name:</label>
<input type="text" class="form-control" name="name" required>
</div>
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<button type="submit" class="btn btn-default">Submit</button>
</form>
This is model Categories.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Categories extends Model
{
public function sections()
{
return $this->belongsTo('App\Models\Sections');
}
public function users()
{
return $this->belongsToMany('App\Models\Users', 'categorie_user');
}
}
And this is model Users.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Users extends Model
{
public function categories()
{
return $this->belongsToMany('App\Models\Categories', 'categorie_user');
}
}
When I add this route under routes as above
Route::group(['prefix' => 'user'], function () {
Route::resource('categories', 'User\CategoriesController');
Route::post('categories/store', ['uses' => 'User\CategoriesController#store']);
});
then everything works like a charm. I'm newbie in Laravel but I think that everything must work with out that route because I use restfull controller. Any sugestions I will appriciated. Thank you.
Finally, I find the answer. According to RESTfull resource controller the URL for form action must be the main route, not /store or /create. So in form action I wrote:
<form action="/user/categories" method="POST">
And that worked for me. Anyway, thanks for help. I hope this will help someone.
change the form action to "/user/categories" like
<form action="/user/categories" method="POST">