问题
Using Laravel 5.2.
I'm developing a Phonebook project in Laravel, where you store contact info in a table named Contacts.
To create new contacts in this table, you have to be registered, and your info will be recorded in a users table
I created a view to show the Contacts table and in the Controller I came up with a logic to only show the contacts that you created in the table. So, it means you cannot see the contacts another user created in the table.
This logic is to prevent the user losing track of its contacts. For example, as a user I created only 2 contacts, but if my table has over 500 entries, I'll have to dig deep in the table to find my contact.
BUT the contacts, specifically the email and phone entries, have to be unique so we don't have repeated info in the table.
And this creates an issue, because I can't see the contact info other users create in this table. SO let's say that me and my brother want to store the contact of my sister only one of us will be able to create this info and only who created it will be able to see this info.
Here is my question
How do I "authorize" the identical contact to show up for an user that didn't created it without losing the unique parameter?
Here is some of my code (including for some clarification):
Users Migration
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class PhonebookUsers extends Migration
{
protected $primaryKey = 'name';
public $incrementing = false;
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->integer('id')->unsigned()->autoIncrement();
$table->string('user_image');
$table->string('name');
$table->string('email', 191)->unique();
$table->string('password', 191);
$table->timestamp('updated_at');
$table->timestamp('created_at');
$table->rememberToken();
});
}
User Validation Parameters
...
public function rules()
{
return [
'user_image' => 'file',
'name' => 'required|alpha|min:3|max:255',
'email' => 'required|unique:users,email|email',
'password' => 'required|alpha_num|between:6,100',
];
}
...
Contacts Migration
...
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->integer('id')->unsigned()->autoIncrement();
$table->integer('user_id')->unsigned();
$table->foreign('user_id')->references('id')->on('users');
$table->string('image');
$table->string('name');
$table->string('lastname');
$table->string('email', 191);
$table->string('phone',191);
$table->string('address');
$table->string('description', 255);
});
}
...
Note that the migration includes a column, user_id, to identify, by id, the user who created a contact.
Contacts Validation Parameters
...
public function rules()
{
return [
'image' => 'file',
'name' => 'alpha|min:3|max:15|required',
'lastname' => 'alpha|min:3|max:15',
'email' => 'required|email|unique:contacts,email',
'phone' => 'required|alpha_num|between:3,25|unique:contacts,phone',
'address' => 'max:255',
'description' => 'max:255'
];
}
...
ContactsController
<?php
namespace App\Http\Controllers;
use App;
use App\Contact as Contact;
use App\User as User;
use DB;
use Illuminate\Http\Request;
use App\Http\Controllers\Auth;
use App\Http\Requests\CreateContactRequest;
use App\Http\Requests\StoreContactRequest;
use Illuminate\Support\Facades\Input;
use Validator;
class ContactsController extends Controller
{
// showing the form in the phonebook.blade.php
// the form is structured using html and stuff
public function index()
{
return view('phonebook');
}
// showing the table where I save my contacts
// simple view stuff
public function tab()
{
if(\Auth::check())
{
$contacts = App\Contact::where('user_id', \Auth::user()->id)->get();
return view('contacts', compact('contacts'));
}
else
{
return view('contacts', compact('contacts'));
}
}
public function create(CreateContactRequest $request)
{
$contact = new Contact;
$contact-> name = $request->get('name');
$contact-> lastname = $request->get('lastname');
$contact-> email = $request->get('email');
$contact-> phone = $request->get('phone');
$contact-> address = $request->get('address');
$contact-> description = $request->get('description');
$contact-> user_id = \Auth::user()->id;
// Checking if input has a file
if ($request->hasFile('image'))
{
// It does, so set name to a random string with 10 chars
$fileName = str_random(10);
// Get the extension of the file (.jpg, .png...)
$fileName .= '.' . $request->file('image')->getClientOriginalExtension();
// Move the file to the storage
$request->file('image')->move(storage_path('app/public/uploads'), $fileName);
// Attribute the contact to the image and then to the name of the file
// one thing "pulling" another
$contact->image = $fileName;
}
// new update: echo the same contacts for different users
// so, the $contact->save(); line would be an else for
// really unique contacts
$contact->save();
$contacts = App\Contact::where('user_id', \Auth::user()->id)->get();
return view('contacts', compact('contacts'));
}
// editing a contact, taking all the info that is in my contacts table according to the id in that row
// permeating an edit form similar to the one in the main form using the edit.blade.php
public function edit($id)
{
$contact = Contact::where('user_id', \Auth::user()->id)->findOrFail($id);
return view('edit', compact('contact'));
}
// Create the update request for the table
public function update($id)
{
$contact = Contact::findOrFail($id);
$contact -> name = Input::get('name');
$contact -> lastname = Input::get('lastname');
$contact -> email = Input::get('email');
$contact -> phone = Input::get('phone');
$contact -> address = Input::get('address');
$contact -> description = Input::get('description');
$contact -> save();
$contacts = App\Contact::where('user_id', \Auth::user()->id)->get();
return view('contacts', compact('contacts'));
}
// deleting an input in my table, called with a link, going to delete.blade.php.
// the function is called when loading the delete.blade.php
public function destroy($id)
{
// finding the id of my contact and deleting
// everything under this id which means
// my entire contact info
$contact = Contact::where('user_id', \Auth::user()->id)->findOrFail($id);
$contact->delete();
// this will return the delete view, which is the confirmation that the code works
return view('delete');
}
// tests about uploading photos. create a button or link in the table to redirect to the upload page
// select a pic using an input form, then use the move method to store my pic in a directory
// but let's begin with simplicity let's just go to the form that'll request the photo
public function upload($id)
{
// simply return the view upload.blade.php that has the form to input my pic
$contact = Contact::where('user_id', \Auth::user()->id)->findOrFail($id);
return view('upload', compact('contact'));
}
// moving the file to a dir
public function move(Request $request, $id)
{
// check if the input has a file
if ($request->hasFile('image')) {
// if it does create a name for the file, a random string with 10 characters (default 40)
$fileName = str_random(10);
// take this name we just created add the file's extension using the original extension
//adiciona extensão da imagem no nome do arquivo
$fileName .= '.' . $request->file('image')->getClientOriginalExtension();
// save image to the right diretory
// Salva a imagem no diretorio selecionado
$request->file('image')->move(storage_path('app/public/uploads'), $fileName);
// Attribute the contact, using its id, to the image uploaded and then to the name of the file
// like in the create method, one thing pulls the other
$contact = Contact::findOrFail($id);
$contact->image = $fileName;
// then save the contact with everything attributed
$contact->save();
}
$contacts = App\Contact::where('user_id', \Auth::user()->id)->get();
// finally return the view
return view('contacts', compact('contacts'));
}
}
Thanks in advance.
回答1:
You can add additional where clause for unique validation as below
'email' => Rule::unique('users')->where(function ($query) {
$query->where('user_id', Auth::user()->id);
})
don't forget to mention use Illuminate\Validation\Rule;
OR Try
While insert
'email' => 'unique:users,email,NULL,id,user_id,'.Auth::user()->id,
While update
'email' => 'unique:users,email,{id of object to edit},id,user_id,'.Auth::user()->id,
In the rule above, only rows with an user_id of Auth::id() would be included in the unique check.
来源:https://stackoverflow.com/questions/44658006/laravel-repeating-entry-with-unique-parameter-for-different-users