рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ URL рдкреАрдврд╝реА (рд╕реАрдПрдирд╕реА)ред рд▓рд╛рд░рд╛рд╡реЗрд▓ 4 + рдерд░реНрдб-рдкрд╛рд░реНрдЯреА рдкреИрдХреЗрдЬ

рдореИрдВ рдпреВрдЖрд░рдПрд▓ рдФрд░ рдЙрдирдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЙрдкрдХрд░рдг рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред

рдХрд╛рд░реНрдп рдЗрддрдирд╛ рдмрдбрд╝рд╛ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд▓рдЧрд╛рддрд╛рд░ рдЙрдарддрд╛ рд╣реИ, рдФрд░ рдореИрдВ рдЗрд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЗрдХрд┐рд▓ рд▓рд┐рдЦрдиреЗ рдореЗрдВ рд▓рдЧрдиреЗ рд╡рд╛рд▓реЗ рд╕рдордп рдХреЛ рдХрдо рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдореИрдВ рд╡рд┐рднрд┐рдиреНрди рд╡рд░реНрдЧреЛрдВ, рд╡рд┐рдзрд┐рдпреЛрдВ, рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЗ рдХреЙрд▓ рдХреЗ рд╡реНрдпрд╛рдкрдХ рдЙрдкрдпреЛрдЧ рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдФрд░ рдЬрдм рднреА рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рдПрдХ рдпреВрдЖрд░рдПрд▓ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВред рдЕрд░реЗ рд╣рд╛рдВ, рдореИрдВ рд▓рд╛рд░рд╡реЗрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдЙрдкрдХрд░рдг рдХреИрдж рд╣реИрдВред

рдЯреВрд▓ рд▓рд┐рдВрдХ




рдпрд╣ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рд╣реИред

рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдмрдпрд╛рди


рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрджреНрд╡рд┐рддреАрдп рдпреВрдЖрд░рдПрд▓ рдХреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдкреАрдврд╝реА / рд╕рдВрд╕рд╛рдзрди / 1 рдХреЗ рдмрдЬрд╛рдп / рд╕рдВрд╕рд╛рдзрди / рдЕрджреНрд╡рд┐рддреАрдп-рд╕рдВрд╕рд╛рдзрди-рдпреВрдЖрд░рдПрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрди рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдПред


рдиреАрдЪреЗ рдЙрддрд░ рд░рд╣рд╛ рд╣реИ


рдорд╛рдирд╛ рдХрд┐ рд╣рдореЗрдВ рдХрдВрдЯреНрд░реА рдФрд░ рд╕рд┐рдЯреА рджреНрд╡рд╛рд░рд╛ рд╕рд╛рдЗрдЯ рдкрд░ рдЦреЛрдЬ рдХреЛ рддреЛрдбрд╝рдирд╛ рд╣реИ, рд▓реЗрдХрд┐рди рддрд╛рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЖрд╕рд╛рдиреА рд╕реЗ рдиреЗрд╡рд┐рдЧреЗрдЯ рдХрд░ рд╕рдХреЗ рдХрд┐ рд╕рд╛рдЗрдЯ рдЙрддреНрдкрд╛рджреЛрдВ рдХреА рд╕реВрдЪреА рджреЗрдЦрддреЗ рд╕рдордп рдХрд┐рд╕ рдХреНрд╖реЗрддреНрд░ / рд╢рд╣рд░ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред

рдЪрд▓реЛ рдПрдХ рдирдИ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдмрдирд╛рдХрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ:

composer create-project laravel/laravel habr_url --prefer-dist 

рдЕрдЧрд▓рд╛, habr_url рдХреА рдЬрдбрд╝ рдореЗрдВ рдХрдВрдкреЛрдЬрд╝рд░ рдЦреЛрд▓реЗрдВред

 { "name": "laravel/laravel", "description": "The Laravel Framework.", "keywords": ["framework", "laravel"], "license": "MIT", "require": { "laravel/framework": "4.1.*", "ivanlemeshev/laravel4-cyrillic-slug": "dev-master", "cviebrock/eloquent-sluggable": "1.0.*", "way/generators": "dev-master" }, "autoload": { "classmap": [ "app/commands", "app/controllers", "app/models", "app/database/migrations", "app/database/seeds", "app/tests/TestCase.php" ] }, "scripts": { "post-install-cmd": [ "php artisan optimize" ], "post-update-cmd": [ "php artisan clear-compiled", "php artisan optimize" ], "post-create-project-cmd": [ "php artisan key:generate" ] }, "config": { "preferred-install": "dist" }, "minimum-stability": "dev" } 

"way/generators": "dev-master" рддреНрд╡рд░рд┐рдд рдкреНрд░реЛрдЯреЛрдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред

рдХрдВрд╕реЛрд▓ рдореЗрдВ composer update рдХрдорд╛рдВрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдФрд░ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд┐рдП рдЧрдП рдкреИрдХреЗрдЬреЛрдВ рдХреЗ рдмрд╛рдж рд╣рдо рдРрдк / рдХреЙрдиреНрдлрд┐рдЧрд░ / рдРрдк рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХрд░рддреЗ рд╣реИрдВред

 <?php return array( // ... 'providers' => array( // ... 'Ivanlemeshev\Laravel4CyrillicSlug\SlugServiceProvider', 'Cviebrock\EloquentSluggable\SluggableServiceProvider', 'Way\Generators\GeneratorsServiceProvider', ), // ... 'aliases' => array( // ... 'Slug' => 'Ivanlemeshev\Laravel4CyrillicSlug\Facades\Slug', 'Sluggable' => 'Cviebrock\EloquentSluggable\Facades\Sluggable', ), ); ?> 

рд╕реНрд▓рдЧ рдХреНрд▓рд╛рд╕ рд╣рдореЗрдВ рд╕рд╛рдЗрд░рд┐рд▓рд┐рдХ рд╕реЗ URL рдЬрдирд░реЗрдЯ рдХрд░рдиреЗ рдХрд╛ рдЕрд╡рд╕рд░ рджреЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╕реНрдЯреИрдгреНрдбрд░реНрдб рд╕реНрдЯреНрд░реИ рдХреНрд▓рд╛рд╕ рдХреЗрд╡рд▓ рд▓реИрдЯрд┐рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИред рдореИрдВ рдереЛрдбрд╝рд╛ рдмрд╛рдж рдореЗрдВ рд╕реБрд╕реНрдд рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реВрдБрдЧрд╛ред

рдХреЛрдб рдЬрдирд░реЗрдЯ рдХрд░реЗрдВ

 php artisan generate:scaffold create_countries_table --fields="name:string:unique, code:string[2]:unique" php artisan generate:scaffold create_cities_table --fields="name:string, slug:string:unique, country_id:integer:unsigned" php artisan generate:scaffold create_products_table --fields="name:string, slug:string:unique, price:integer, city_id:integer:unsigned" 

рд╣рдо рд╡рд┐рджреЗрд╢реА рдХреБрдВрдЬреА рдЬреЛрдбрд╝рдХрд░ рдирдИ рдлрд╛рдЗрд▓реЗрдВ рдмрджрд▓рддреЗ рд╣реИрдВ:

 //  app/database/migrations/____create_cities_table.php class CreateCitiesTable extends Migration { // ... public function up() { Schema::create('cities', function(Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('slug')->unique(); $table->integer('country_id')->unsigned()->index(); $table->foreign('country_id')->references('id')->on('countries')->onDelete('cascade'); $table->timestamps(); }); } // ... } 

 //  app/database/migrations/____create_products_table.php class CreateProductsTable extends Migration { // ... public function up() { Schema::create('products', function(Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('slug')->unique(); $table->integer('price'); $table->integer('city_id')->unsigned()->index(); $table->foreign('city_id')->references('id')->on('cities')->onDelete('cascade'); $table->timestamps(); }); } // ... } 

рдФрд░ seeds рдорд╛рдзреНрдпрдо рд╕реЗ рдХреБрдЫ рджреЗрд╢реЛрдВ рдФрд░ рд╢рд╣рд░реЛрдВ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВред рдПрдкреНрд▓рд┐рдХреЗрд╢рди / рдбреЗрдЯрд╛рдмреЗрд╕ / рдмреАрдЬ рдлрд╝реЛрд▓реНрдбрд░ рдЦреЛрд▓реЗрдВ рдФрд░ рджреЛ рдлрд╛рдЗрд▓реЗрдВ рдмрджрд▓реЗрдВ:

 //  app/database/seeds/CountriesTableSeeder.php class CountriesTableSeeder extends Seeder { public function run() { $countries = array( array('name' => '', 'code' => 'ru'), array('name' => '', 'code' => 'ua') ); // Uncomment the below to run the seeder DB::table('countries')->insert($countries); } } 

 //  app/database/seeds/CitiesTableSeeder.php class CitiesTableSeeder extends Seeder { public function run() { // Uncomment the below to wipe the table clean before populating // DB::table('cities')->truncate(); $cities = array( array('name' => '', 'slug' => Slug::make(''), 'country_id' => 1), array('name' => '-', 'slug' => Slug::make('-'), 'country_id' => 1), array('name' => '', 'slug' => Slug::make(''), 'country_id' => 2), ); // Uncomment the below to run the seeder DB::table('cities')->insert($cities); } } 

рдпрд╣ Slug::make($input) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд░реВрдк рдореЗрдВ $input рд▓реЗрддрд╛ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рд╕реЗ moskva рдпрд╛ sankt-peterburg рд╕рдорд╛рди рдХреБрдЫ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИред

рдЕрдм рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдмрджрд▓рддреЗ рд╣реИрдВ:

 //  app/config/database.php return array( // ... 'connections' => array( // ... 'mysql' => array( 'driver' => 'mysql', 'host' => 'localhost', 'database' => 'habr_url', 'username' => 'habr_url', 'password' => 'habr_url', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ), ), // ... ); 

рдФрд░ рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕реНрдХреАрдо рдФрд░ рдбреЗрдЯрд╛ рд▓рд╛рддреЗ рд╣реИрдВред

 php artisan migrate --seed 

рдФрд░ рдпрд╣рд╛рдБ рд╣реИ рдХрд┐ рд╣рдо рдХреНрдпрд╛ рдорд┐рд▓рд╛:




рд▓рд┐рдВрдХ рдореЙрдбрд▓ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдо рдЬреЛрдбрд╝реЗрдВ:

 //  app/models/Product.php class Product extends Eloquent { protected $guarded = array(); public static $rules = array( 'name' => 'required|alpha_num|between:2,255', 'slug' => 'required|alpha_num|between:2,255|unique:products,slug', 'price' => 'required|numeric|between:2,255', 'city_id' => 'required|exists:cities,id' ); public function city() { return $this->belongsTo('City'); } } 

 //  app/models/City.php class City extends Eloquent { protected $guarded = array(); public static $rules = array( 'name' => 'required|alpha_num|between:2,255', 'slug' => 'required|alpha_num|between:2,255|unique:cities,slug', 'country_id' => 'required|exists:countries,id' ); public function country() { return $this->belongsTo('Country'); } public function products() { return $this->hasMany('Product'); } } 

 //  app/models/Country.php class Country extends Eloquent { protected $guarded = array(); public static $rules = array( 'name' => 'required|alpha_num|between:2,255|unique:countries,name', 'code' => 'required|alpha|size:2|unique:countries,code' ); public function cities() { return $this->hasMany('City'); } public function products() { return $this->hasManyThrough('Product', 'City'); } } 

CitiesController рдФрд░ ProductsController рдореЗрдВ store рддрд░реАрдХреЛрдВ рдХреЛ CitiesController рд╕реЗ CitiesController ред

 //  app/models/CitiesController.php class CitiesController extends BaseController { // ... public function store() { $input = Input::all(); $input['slug'] = Slug::make(Input::get('name', '')); // ! $validation = Validator::make($input, City::$rules); if ($validation->passes()) { $this->product->create($input); return Redirect::route('products.index'); } return Redirect::route('products.create') ->withInput() ->withErrors($validation) ->with('message', 'There were validation errors.'); } // ... } 

 //  app/models/ProductsController.php class ProductsController extends BaseController { // ... public function store() { $input = Input::all(); $input['slug'] = Slug::make(Input::get('name', '')); // ! $validation = Validator::make($input, Product::$rules); if ($validation->passes()) { $this->product->create($input); return Redirect::route('products.index'); } return Redirect::route('products.create') ->withInput() ->withErrors($validation) ->with('message', 'There were validation errors.'); } // ... } 

рдФрд░ рдРрдк / рд╡рд┐рдЪрд╛рд░реЛрдВ / рд╢рд╣рд░реЛрдВ / create.blade.php , рдРрдк / рджреГрд╢реНрдпреЛрдВ / рд╢рд╣рд░реЛрдВ / edit.blade.php , рдРрдк / рд╡рд┐рдЪрд╛рд░реЛрдВ / рдЙрддреНрдкрд╛рджреЛрдВ / create.blade.php , рдРрдк / рд╡рд┐рдЪрд╛рд░реЛрдВ / рдЙрддреНрдкрд╛рджреЛрдВ / edit.blade.php рд╕реЗ рдирд┐рдХрд╛рд▓реЗрдВ рддрддреНрд╕рдо рд░реВрдк рддрддреНрд╡ред

рдорд╣рд╛рди, URL рдЬрдирд░реЗрдЯ рдХрд┐рдП URL рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрджрд┐ рд╡реЗ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рд╣реИрдВ, рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? рдПрдХ рддреНрд░реБрдЯрд┐ рдЙрддреНрдкрдиреНрди рд╣реЛрдЧреАред рдФрд░ рдЗрд╕рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП - рдпрджрд┐ slug рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдореЗрдВ рдПрдХ рдЙрдкрд╕рд░реНрдЧ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдФрд░ рдпрджрд┐ рдХреЛрдИ рдЙрдкрд╕рд░реНрдЧ рд╣реИ, рддреЛ рдЗрд╕реЗ рдмрдврд╝рд╛рдПрдВред рдмрд╣реБрдд рд╕рд╛рд░реЗ рдХрд╛рдо, рд▓реЗрдХрд┐рди рдХреЛрдИ рд▓рд╛рд▓рд┐рддреНрдп рдирд╣реАрдВред рдЗрди рдЗрд╢рд╛рд░реЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо Eloquent Sluggable рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред

рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рдЪрд▓реЛ рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ Eloquent Sluggable рд▓рд┐рдП рд╡рд┐рдиреНрдпрд╛рд╕ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ:

 php artisan config:publish cviebrock/eloquent-sluggable 

рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдлрд╝рд╛рдЗрд▓ рдореЗрдВ, рдЬреЛ рдпрд╣рд╛рдВ рдРрдк / рдХреЙрдиреНрдлрд┐рдЧрд░ / cviebrock / eloquent-sluggable / config.php рд╣реИ, рд╡рд┐рдХрд▓реНрдк 'method' => null рдХреЛ 'method' => array('Slug', 'make') рдмрджрд▓реЗрдВред рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╕рд┐рд░рд┐рд▓рд┐рдХ рдкрд╛рддреНрд░реЛрдВ рд╕реЗ рд▓рд┐рдкреНрдпрдВрддрд░рдг рдореЗрдВ рдФрд░ URL рдмрдирд╛рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рд╕реНрд▓рдЧ рд╡рд░реНрдЧ (рдорд╛рдирдХ Str рдХреЗ рдмрдЬрд╛рдп, рдЬрд┐рд╕реЗ рдпрд╣ рдирд╣реАрдВ рдкрддрд╛ рд╣реИ рдХрд┐ Cyrillic рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рд╣реИ) рдХреЛ рд╕реМрдВрдкрд╛ рдЬрд╛рдПрдЧрд╛ред

рдпрд╣ рдкреИрдХреЗрдЬ рдХрд┐рд╕рдХреЗ рд▓рд┐рдП рдЕрдЪреНрдЫрд╛ рд╣реИ? рдпрд╣ рдЗрд╕ рд╕рд┐рджреНрдзрд╛рдВрдд рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ: рдпрд╣ eloquent.saving* рдШрдЯрдирд╛ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИ, рдФрд░ рдореЙрдбрд▓ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдореЗрдВ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдлрд╝реАрд▓реНрдб рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди slug рдХреЛ рд▓рд┐рдЦрддрд╛ рд╣реИред рд╡рд┐рдиреНрдпрд╛рд╕ рдЙрджрд╛рд╣рд░рдг:

 //  app/models/City.php class City extends Eloquent { protected $guarded = array(); public static $rules = array( 'name' => 'required|alpha_num|between:2,255', 'country_id' => 'required|exists:countries,id' ); //   public static $sluggable = array( 'build_from' => 'name', 'save_to' => 'slug', ); public function country() { return $this->belongsTo('Country'); } public function products() { return $this->hasMany('Product'); } } 

рдпрджрд┐ рдпрд╣ рдПрдХ рдореМрдЬреВрджрд╛ slug рдореЗрд▓ рдЦрд╛рддрд╛ рд╣реИ, рддреЛ рдЙрдкрд╕рд░реНрдЧ -1 , -2 , рдФрд░ рдЗрд╕реА рддрд░рд╣ рдирдП рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╣рдо slug рд▓рд┐рдП CitiesController@store рдирд┐рдпрдо рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ CitiesController@store рд╡рд┐рдзрд┐ рдореЗрдВ рд▓рд╛рдЗрди $input['slug'] = Slug::make(Input::get('name', '')); рдХреЛ CitiesController@store $input['slug'] = Slug::make(Input::get('name', '')); ред

рд╣рдо Product рд▓рд┐рдП рднреА рдРрд╕рд╛ рд╣реА рдХрд░реЗрдВрдЧреЗ:

 //  app/models/Product.php class Product extends Eloquent { protected $guarded = array(); public static $rules = array( 'name' => 'required|alpha_num|between:2,255', 'price' => 'required|numeric|between:2,255', 'city_id' => 'required|exists:cities,id' ); public static $sluggable = array( 'build_from' => 'name', 'save_to' => 'slug', ); public function city() { return $this->belongsTo('City'); } } 

рдПрдХ рдФрд░ рднреА рджрд┐рд▓рдЪрд╕реНрдк рдмрд╛рдд рдЬреЛ рд╣рдо рдЗрд╕ slug рд╕рд╛рде рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рд╡рд╣ рдпрд╣ slug рдХрд┐ рдЕрдЧрд░ рд╣рдо City рдореЙрдбрд▓ рдореЗрдВ $sluggable рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдлрд┐рд░ рд╕реЗ $sluggable :

 //  app/models/City.php class City extends Eloquent { protected $guarded = array(); public static $rules = array( 'name' => 'required|alpha_num|between:2,255', 'slug' => 'required|alpha_num|between:2,255|unique:cities,slug', 'country_id' => 'required|exists:countries,id' ); public static $sluggable = array( 'build_from' => 'name_with_country_code', 'save_to' => 'slug', ); public function country() { return $this->belongsTo('Country'); } public function products() { return $this->hasMany('Product'); } public function getNameWithCountryCodeAttribute() { return $this->country->code . ' ' . $this->name; } } 

рд╣рд╛рдВ, рд╣рдо рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдЧреИрд░-рдореМрдЬреВрджрд╛ рдлрд╝реАрд▓реНрдб рдХрд╛ рдЪрдпрди рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕реЗ рд╕рд╣рд╛рдпрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред

рдереЛрдбрд╝реЗ рдмрджрд▓реЗ рд╣реБрдП CitiesTableSeeder рд╣рдо рд╡рд╛рдВрдЫрд┐рдд рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗ:

 //  app/database/seeds/CitiesTableSeeder.php class CitiesTableSeeder extends Seeder { public function run() { // Uncomment the below to wipe the table clean before populating // DB::table('cities')->truncate(); $cities = array( array('name' => '', 'country_id' => 1), array('name' => '-', 'country_id' => 1), array('name' => '', 'country_id' => 2), ); // Uncomment the below to run the seeder foreach ($cities as $city) { City::create($city); } } } 

рдЕрдм рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдХреЛ рд╡рд╛рдкрд╕ рд▓реЗрдВ рдФрд░ рдЗрд╕реЗ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рдирдП рдХреЗ рд╕рд╛рде рднрд░реЗрдВ:

 php artisan migrate:refresh --seed 




рдХреБрдЫ рдорд╛рд░реНрдЧ рдЬреЛрдбрд╝реЗрдВ:

 //  app/routes.php // ... Route::get('country/{code}', array('as' => 'country', function($code) { $country = Country::where('code', '=', $code)->firstOrFail(); return View::make('products', array('products' => $country->products)); })); Route::get('city/{slug}', array('as' => 'city', function($slug) { $city = City::where('slug', '=', $slug)->firstOrFail(); return View::make('products', array('products' => $city->products)); })); Route::get('product/{slug}', array('as' => 'product', function($slug) { $product = Product::where('slug', '=', $slug)->firstOrFail(); return View::make('product', compact('product')); })); 

рдФрд░ рдХреБрдЫ рдкреИрдЯрд░реНрди рдЬреЛрдбрд╝реЗрдВ:

 <!--  app/views/nav.blade.php --> <ul class="nav nav-pills"> @foreach(Country::all() as $country) <li><a href="{{{ route('country', $country->code) }}}">{{{ $country->name }}}</a> @endforeach </ul> 

 <!--  app/views/products.blade.php --> @extends('layouts.scaffold') @section('main') @include('nav') <h1>Products</h1> @if ($products->count()) <table class="table table-striped table-bordered"> <thead> <tr> <th>Name</th> <th>Price</th> <th>City</th> </tr> </thead> <tbody> @foreach ($products as $product) <tr> <td><a href="{{{ route('product', $product->slug)}}}">{{{ $product->name }}}</a></td> <td>{{{ $product->price }}}</td> <td><a href="{{{ route('city', $product->city->slug) }}}">{{{ $product->city->name }}}</a></td> </tr> @endforeach </tbody> </table> @else There are no products @endif @stop 

 <!--  app/views/product.blade.php --> @extends('layouts.scaffold') @section('main') @include('nav') <h1>Product</h1> <table class="table table-striped table-bordered"> <thead> <tr> <th>Name</th> <th>Price</th> <th>City</th> </tr> </thead> <tbody> <tr> <td>{{{ $product->name }}}</td> <td>{{{ $product->price }}}</td> <td><a href="{{{ route('city', $product->city->slug) }}}">{{{ $product->city->name }}}</a></td> </tr> </tbody> </table> @stop 

рд╡рд╣ рд╕рдм рд╣реИред

рдбреЗрдореЛ рдФрд░ рдЧрд┐рдЯ




рддреНрд░реБрдЯрд┐рдпреЛрдВ, рд╣рдореЗрд╢рд╛ рдХреА рддрд░рд╣ рдкреАрдПрдо рдореЗрдВред рд╕реБрдЭрд╛рд╡ рдФрд░ рдЖрд▓реЛрдЪрдирд╛ - рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВред рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

Source: https://habr.com/ru/post/In208678/


All Articles