It’s times like this that I want to kiss +Taylor Otwell (and +Shawn McCool for his form-base-model bundle).
$interests = RegistrationForm::get('interests'); $user->interests()->sync($interests);
How beautifully simple and yet it hides such wonderful functionality.
What’s going on?
I’m building a registration form where users can select multiple checkboxes to indicate their interest in multiple items.
This requires a few tables and some incredibly simple models.
The Interests table migration
class Create_Interests_Table { public function up() { Schema::create('interests', function($table) { $table->increments('id')->unsigned(); $table->integer('category_id')->unsigned(); $table->string('name'); $table->string('slug')->unique(); }); } }
We can ignore the category_id here as I’m using it for something else, the other columns are nice and simple though. We have our incrementing id, the name of our interest, and a slug for the interest (which is going to be used later on for SEO friendly filtering URLs).
The Interest_user table migration
class Create_Interest_User_Table { public function up() { Schema::create('interest_user', function($table) { $table->increments('id')->unsigned(); $table->integer('user_id')->unsigned(); $table->integer('interest_id')->unsigned(); $table->timestamps(); }); } }
This is all pretty straight forward as well. An id, and then the relational user_id and interest_id.
The user model
This is a small excerpt of my User model.
public function interests() { return $this->has_many_and_belongs_to('Interest'); }
Yes, it’s that beautiful.
My form (a little excerpt)
I can build the checkboxes nice and easily with:
foreach ($interest_category['interests'] as $interest_id => $interest_name) { echo Form::checkbox('interests[]', $interest_id, in_array($interest_id, (array) RegistrationForm::old('interests'))) . ' ' . __('interests.' . $interest_id); }
There is a little bit of other stuff going on before this, but ultimately I’m grabbing an array of interests from the database and feeding them out to checkboxes. I still have to arrange the label, but I’m just testing this out at the moment. I’m building a multilingual site so I’m having to do some interesting things to ensure correctly localised labels are returned.
The registration controller
So I have my users table, my interests table and my interest_user table. The user has been created with:
// Save the User $user = new User($user_data); $user->save();
So I now have a user object and I can so easily sync the interests to the user and Laravel takes care of the rest. It populates the relational table with the user id and each interest id.
// Save the interests $interests = RegistrationForm::get('interests'); $user->interests()->sync($interests);
Isn’t that just fantastic! If you’d like more information on building many-to-many relationships in Laravel check out the official documentation. What’s that RegistrationForm class? Check out the form-base-model bundle on github.
Comments