rakete
rakete

Reputation: 3051

Order items logic with Laravel

For my Laravel-application I've implemented a sort-functionality. In the list of the options I show two buttons (up and down) which trigger the functions up and down in the OptionController (see below).

Question 1

At the moment I am justing a DECIMAL(30,15) field for the sort-column in the database. I choose this 30,15 randomly. Can you give me an advice, which DECIMAL(?,?) is best for this sort field?

Question 2

I want to move the up and down logic to a place, where I can use it in different controllers with generic models (e.g. Sort::up($models, $item). What would be the right place to place such a logic? Service? Helper-function? ...?

Question 3

When I create a new item (e.g. option in my example below) I need to set the sort automatically to the sort of the last item + 1. Of course, I could do this in the controller when storing it, but can I put this logic to the model itself? And: Where can I put this logic to use it in more than one model without repeating the code?

namespace App\Http\Controllers;


use App\Models\Option;
use App\Models\Attribute;

class OptionController extends Controller
{

    public function up($id, $attributeId) {
      $options = Attribute::findOrFail($attributeId)->options;
      $option = Option::findOrFail($id);

      foreach ($options as $index => $o) {

        // Search for the current position of the
        // option we have to move.
        if( $option->id == $o->id ) {

          // Will be first element?
          if( $index == 1) {

            // Set the sort to current first element sort - 1
            $option->sort = $options[0]->sort-1;

          } else if( $index > 1) {

            // Get the previous and the pre-previous items from the options
            $pre = $options[$index-1]->sort;
            $prepre = $options[$index-2]->sort;

            $diff = ($pre - $prepre) / 2;

            $option->sort = $prepre + $diff;
          }

          break;
        }
      }

      $option->save();

            Session::flash('message', __(':option moved up.', [ 'option' => $option->name ]));
      Session::flash('message-type', 'success');

      return redirect()->back();
    }

    public function down($id, $attributeId) {
      $options = Attribute::findOrFail($attributeId)->options;
      $option = Option::findOrFail($id);

      foreach ($options as $index => $o) {

        // Search for the current position of the
        // option we have to move.
        if( $option->id == $o->id ) {

          // Will be last element?
          if( $index == count($options)-2 ) {

            // Set the sort to current last element sort + 1
            $option->sort = $options[count($options)-1]->sort+1;

          } else if( $index < count($options)-2) { // ???

            // Get the previous and the pre-previous items from the options
            $next = $options[$index+1]->sort;
            $nextnext = $options[$index+2]->sort;

            $diff = ($nextnext - $next) / 2;

            $option->sort = $next + $diff;
          }

          break;
        }
      }

      $option->save();

      Session::flash('message', __(':option moved down.', [ 'option' => $option->name ]));
      Session::flash('message-type', 'success');

      return redirect()->back();
    }
}

Upvotes: 0

Views: 234

Answers (1)

Zoli
Zoli

Reputation: 1091

You can use a trait for this. See link for more details.

Upvotes: 1

Related Questions