One place for hosting & domains

      Binding

      Cleaner Laravel Controllers with Route Model Binding


      Introduction

      Laravel as a framework either for building websites or a container to build APIs (lumen) has evolved as a developer’s framework of choice. Laravel comes with a lot of growing features – take for example Laravel’s events. Events in Laravel used to be a simple pub-sub library, but now Laravel events can broadcast all the way to the client and allows us to create real-time apps.

      But that’s beside the point, today’s celebrity is Laravel’s route model binding.

      What is Route Model Binding

      Route model binding in Laravel provides a mechanism to inject a model instance into your routes. Still not clear on the meaning, here is an example. Say we want to get a post from the database, we could do something like this:

      ...
      // the route parameter is the id of the post
      // for example http://example.com/posts/53
      Route::get('posts/{id}', function ($id) {
      
        // we have to find the post using the $id
        $post = Post::find($id);
      
        // if there is no post, 404
        if (!$post) return abort(404);
      
        // return the view and the post
        return view('post.show', compact('post'));
      });
      ...
      

      We could further go on to simplify this method into

      ...
      // the route parameter is the id of the post
      // for example http://awesome.dev/posts/53
      Route::get('posts/{id}', function ($id) {
      
        // find the post or 404 if not found
        $post = Post::findOrFail($id);
      
        // return the view and the post
        return view('post.show', compact('post'));
      });
      ...
      

      But route model binding helps us get rid of extra keystrokes by simplifying both instances above into

      ...
      // by using $post, we can inject the Post object
      Route::get('posts/{post}', function ($post) {
      
        // we now have access to the $post object! no code necessary
      
        // return the view and the post
        return view('post.show', compact('post'));
      });
      ...
      

      This is made possible by telling Laravel to inject a Post model into any route controller that has a {post} parameter attached to it.

      Laravel currently supports two types of route model bindings. We have:

      • Implicit model binding
      • explicit model binding

      Note: The example of route model binding listed above is explicit.

      Implicit Model Binding

      While we’ve seen explicit model binding, here’s an example of implicit model binding now:

      Route::get('posts/{post}', function (AppPost $post) {
        // be awesome. enjoy having the $post object
      });
      

      Laravel is smart enough to know that since a Post model is being injected into the controller closure, it should get the id parameter from the route and get the details for the user.

      Accessing a post will still be done using http://awesome.example.com/posts/24.

      Changing the Model’s Route Key

      If you would like the implicit model binding to use a database column other than id when retrieving models, you may override the getRouteKeyName method on your Eloquent model.

      For instance, if we wanted to use the slug instead of the id, we could do the following:

      class Post extends Model {
        public function getRouteKeyName() {
          return 'slug';
        }
      }
      

      Then we could access our route using http://awesome.example.com/posts/my-post-slug instead of http://awesome.example.com/posts/24.

      Explicit Model Binding

      Just like the name implies, you have to explicitly tell Laravel you want it to bind a url parameter to a particular model. There are two ways to do this, we could bind a parameter to a model using the provided Route facade or carry out this binding in app/Providers/RouteServiceProvider.php (I prefer this method).

      Using the Route Facade

      Using the Route facade to bind a parameter to a model, we can do something like this:

      Route::bind('post', 'AppPost');
      

      We could also give our binding more meaning, for example, what if we want a post only if is a draft? For that, we could change the second parameter of the Route::bind to a closure which takes the route parameter as its value.

      Route::bind('post', function ($value) {
        return AppPost::find($value)->where('status', '=', 'published')->first();
      });
      

      Using the RouteServiceProvider

      The only difference between using the Route facade and RouteServiceProvider class is that – registering your bindings is done in the boot method of the RouteServiceProvider class (location is app/Providers directory) and the bind method is called on the $router object injected into the method. Quick example

      public function boot(Router $router)
      {
        parent::boot($router);
      
        $router->bind('post', function ($value) {
          return AppPost::find($value)->where('status', '=', 'published')->first();
        });
      }
      

      Custom Exceptions for Route Model Binding

      I build a lot of APIs, so custom exceptions for route model bindings are actually more useful for people like me. Laravel provides an easy way for us to do this. Still in the boot method of the RouteServiceProvider class, call the model method on the $router object.

      The model method takes three arguments, the arguments are similar to that of the bind method, with a new addition the third argument which is a closure that throws the new exception.

      $router->model($routeParameter, $modelToBind, function () {
        throw new NotFoundHTTPException;
      });
      

      Conclusion

      You can read more about route model binding in the documentation.

      Hopefully this small, but neat feature can save you a few lines of code in your projects and make your controllers that much cleaner.



      Source link

      Using v-model for Two-Way Binding in Vue.js


      While this tutorial has content that we believe is of great benefit to our community, we have not yet tested or
      edited it to ensure you have an error-free learning experience. It’s on our list, and we’re working on it!
      You can help us out by using the “report an issue” button at the bottom of the tutorial.

      Vue’s two-way binding system takes one of the trickiest parts of developing a web application, user input synchronization, and makes it dead simple with v-model. The v-model directive updates the template whenever the model changes and updates data model whenever the template changes.

      Two-way binding is a powerful feature that, if used properly, can significantly speed up your development process. It reduces the complexity of keeping user input consistent with the application data model.

      In Vue, two-way binding is accomplished using the v-model directive.

      Binding to Text Input Elements

      To bind the value of an input element to a property of your component’s data, use v-model="dataProperty" like so.

      Here’s the component’s data method:

      data() {
        return {
          existentialQuestion: 'Am I truly an alligator?'  
        };
      }
      

      And the template:

      <h2>My deepest, darkest question: {{existentialQuestion}}</h2>
      <input v-model="existentialQuestion"/>
      

      Here it is in a live demo:

      See the Pen poyLjqY by alligatorio (@alligatorio) on CodePen.

      Notice the input value starts out as Am I truly an alligator?, but when you change the input, the existentialQuestion property (and the h2 element) will update in real time.

      Binding to Checkboxes and Radio Buttons

      Checkboxes and radio buttons work pretty much like input elements. A checkbox binding will either be true or false, while a radio button binding will be whatever the contents of its value property is.

      Additionally, a set of checkboxes can be bound to a single array, which will put the contents of their value property in the array if checked.

      Single Checkbox Example

      The component data…

      data() {
        return {
          statementIsTrue: true  
        };
      }
      

      …and the template

      <p>You have decided this statement is {{statementIsTrue}}</p>
      <label>
        <input type="checkbox" v-model="statementIsTrue"/>
        Is this statement true?
      </label>
      

      …and try it live:

      See the Pen abNYvxd by alligatorio (@alligatorio) on CodePen.

      Multiple Checkbox Example

      The component data…

      data() {
        return {
          namesThatRhyme: []  
        };
      }
      

      …and the template

      <p>A list of names that rhyme: {{namesThatRhyme.join(', ')}}</p>
      <label>
        <input type="checkbox" value="Daniel" v-model="namesThatRhyme"/>
        Daniel
      </label>
      <label>
        <input type="checkbox" value="Nathaniel" v-model="namesThatRhyme"/>
        Nathaniel
      </label>
      <label>
        <input type="checkbox" value="Hubert" v-model="namesThatRhyme"/>
        Hubert
      </label>
      

      …and the demo:

      See the Pen NWNYGZE by alligatorio (@alligatorio) on CodePen.

      Radio Button Example

      The component data…

        data() {
          return {
            howAreYouFeeling: "great"
          };
        }
      

      …and the template

      <p>How are you feeling today?</p>
        <label>
          <input type="radio" value="great" v-model="howAreYouFeeling" />
          great
        </label>
        <label>
          <input type="radio" value="wonderful" v-model="howAreYouFeeling" />
          wonderful
        </label>
        <label>
          <input type="radio" value="fantastic" v-model="howAreYouFeeling" />
          fantastic
        </label>
        <p>I am also feeling <em>{{howAreYouFeeling}}</em> today.</p>
      

      Here it is in a demo:

      See the Pen gOreaVe by alligatorio (@alligatorio) on CodePen.

      Notes

      • By default, v-model is evaluated every time the input event is fired (ie. on keypress or paste.) If you’d rather wait until the user has finished inputting and unfocused the field, you can use the v-model.lazy modifier to have v-model listen to the change event instead.
      • If you’d like to cast user input to a number instead of a string, add the v-model.number modifier. You’ll have to handle casting to other types yourself.
      • The v-model.trim modifier will strip and leading or trailing whitespace from the bound string. This (obviously) cannot be used in conjunction with v-model.number.
      • While v-model=“dataProperty” seems like magic at first glance, it’s actually just short-hand for :value="dataProperty" @input="dataProperty = $event.target.value". As such, you can easily implement v-model support for your own components.



      Source link