Rake routes не работает

Routes. The Beginning

Роуты в рельсах очень важная вещь. Но до поры до времени можно даже не обращать внимание на них. Особенно если вы пользуетесь командой scaffold, которая автоматически все прописывает. Но в какой-то момент появляется необходимость создавать нестандартные роуты. Это значит самое время залезать в файл routes.rb в папке config вашего проекта.

Что такое роуты

К практике

Давайте создадим тестовый проект, с которым мы будем шаманить. (Если вы это делает впервые, то можно обсудить в комментариях процесс установки рельс и создания приложения).

rails routes
cd routes

Окей. Проект создан и мы вошли в рабочую папку. Сразу набросимся на роуты:

эта команда вам выдаст две строчки стандартных роутов.
/:controller/:action/:id
/:controller/:action/:id.:format

Это значит, что любой урл сейчас будет парситься по этим двум правилам.
:controller — это Контроллер =). Это компонент MVC, который чаще всего выступает как посредник между Представлением (HTML) и Моделью (база данных, скажем). Дальше будет яснее, но скорее всего вы итак знаете, что это такое.
:action — это вызываемый метод контроллера. У контроллера обычно много методов.
:id — если я вно не указывать запрет на создание id, то по умолчанию любая модель (таблица БД) создается с полем id. Поэтому любой элемент модели имеет id. И когда вы хотите удалить/редактировать/что угодно делать с каким-то конкретным элементом модели вы обязаны передать в контроллер этот самый id.

Окей. Давайте мы создадим новостной журнал. Для этого нам нужны:
— Таблица news в нашей базе данных (Модель). В БД мы будем хранить заголовок статьи (title), автора статьи (author) и собственно саму статью (article)
— Набор методов для работы с БД (Контроллер)
— HTML формы для ввода, редактирования, чтения новостей (Представление)
Мы можем создавать все это по отдельности. Но сейчас мы упростим себе задачу и используем функцию scaffold для генерации пачки готовых файлов.

Читайте также:  Не работает вентилятор отопителя ниссан кашкай j11

./script/generate scaffold Magazine title:string author:string article:text

Мы только что создали все выше перечисленное (а также Helpers, о которых как-нибудь в другой раз). Также команда scaffold сама создала необходимые роуты. Еще раз наберите команду rake routes и вывалится кипа новых роутов

Теперь мы запустим сервер и поиграемся с журналом. Но сперва мы создадим нашу базу данных и запустим миграции.

rake db:create
rake db:migrate
./script/server

Наш журнал теперь доступен по адресу localhost:3000/magazines
Создайте пару новых статей.

Вернемся к таблице роутов выше. Первый столбец — это именные роуты. Они очень удобны. Есть несколько вариантов сейчас сделать ссылку на создание новой статьи. Откройте файл app/views/magazines/index.html.erb — это представление для метода index в контроллере magazines_controller.
В самом низу давайте допишем немного кода.

Самым правильным будет использование последних двух методов. Разница в том, что url возвращает полную ссылку (http://localhost:3000/magazines/new), а path только путь (/magazines/new). Почему лучше пользоваться именными роутами? Именной роут это переменная, изменив которую вы меняете все ссылки, которые пользуются этим роутом. Писать пути от руки вобще не рекомендуется, если приспичило, то лучше написать :action => ‘new’ (зачастую именных роутов на все случаи жизне не хватает, поэтому этот вариант очень распространен).

Второй столбец таблицы — это метод запроса. Одна и таже ссылка, но с разным методом ведет на разные методы контроллера. К примеру, в том же app/views/magazines/index.html.erb:

:delete %>
В первой ссылке исполняется дефолтный GET запрос (можно не указывать в ссылке :method=>:get), а во второй отправляется метод :delete. А ссылка magazine остается в обоих случаях одинаковая.

Третий столюбец — это собственно ссылки, которые мы получим в HTML. Последний столбец — это соответствие ссылок контроллеру и методу. Как уже выше писалось, любую ссылку можно представить в виде пары :controller, :action (ну и иногда :method).

‘blogs’, :action=>’show’, :id=>’1′, :method=>’GET’ %>
Так мы получим ссылку на блог с индексом 1. (Тут метод :get можно было и не указывать)
‘show’, :id => ‘1’ %>
Ссылка на статью с индексом 1. Контроллер и HTTP метод в данном случае указывать не надо, так как GET исполняется по умолчанию, а контроллер, если не указан, выполняется тот же.

Тепрь откройте файл config/routes.rb (можете удалить весь закомментированный текст)

map.resources :magazines
map.connect ‘:controller/:action/:id’
map.connect ‘:controller/:action/:id.:format’

Первую строчку вставила команда scaffold. Эта строчка и добавила нам пачку роутов, которую мы наблюдали выше.

Если вы сейчас наберете просто localhost:3000 вы попадете на приветственную страницу. Давайте это исправим.

map.root :controller => ‘magazines’

Теперь из папки public удалите index.html и зайдя на localhost:3000 вы попадете напрямую куда надо =). Кроме того если вы просмотрите все роуты занова (rake routes), то увидите новый именной роут root. И в меню сможете сделать ссылку на «Главную» вида:

И вы всегда без ущерба ссылкам сможете изменить домашнюю страницу, скажем, на ваш магазин map.root :controller => ‘shop’

II уровень

Собственно создав root вы создали первый именной роут своими руками.
Давайте создадим именной роут «localhost:3000/zhurnal». Не хотим мы буржуйский ‘magazines’, хотим ‘zhurnal’!

map.zhurnal ‘/klevi_zhurnal/:id’, :controller => ‘magazines’, :id => nil

Итак, мы создали именной роут zhurnal, урл которого будет выглядеть как localhost:3000/klevi_zhurnal, а контент он будет получать от контроллера magazines. Если мы попробуем прочесть статью теперь вроде localhost:3000/klevi_zhurnal/1 — то мы обламаемся. Внесем в наш роут немного изменений:

map.zhurnal ‘/klevi_zhurnal/:action/:id’, :controller => ‘magazines’, :action => ‘index’, :id => nil

Что все это значит:
— урл вида /klevi_zhurnal/ будет отработан :controller => ‘magazines’, :action => ‘index’, :id => ‘nil’ — то есть мы получим индексовую страницу (index.html.erb)
— /klevi_zhurnal/1 выплюнет ошибку, что action ‘1’ не существует (посмотрите на последовательность передачи аргумента в роуте)
— /klevi_zhurnal/show скажет, что ID не указано
— /klevi_zhurnal/show/1 — выдаст вам статью с (если она конечно существует)
— /klevi_zhurnal/edit/1 — выдаст форму редактирования этой статьи

Правда теперь несколько тяжелее выглядят сами ссылки:
Вместо будет
Вместо будет ‘show’, :id=>’1′) %>

Обратите внимание на то, что для лучшего понимания роутов введена система множественного/единственного числа:
показать все статьи magazines_path,
показать отдельную статью: magazine_path.
Чорт — не самое правильное слово вообще выбрал =). Если бы у нас все называлось Article:
index => articles_path, show => article_path(:id)

Теперь давайте создадим новый метод.
Откройте app/controllers/magazines_controller.rb
Добавьте туда метод

def random
offset = rand(Magazine.count :all)
@magazine = Magazine.find(:first, :offset => offset)
render :action => ‘show’
end

Этот метод просто возвращает рандомно статью. Давайте попробуем его вызвать: localhost:3000/magazines/random
Получаем ошибку — требует от нас ID. Почему? Потому что стандартный роут продразумевает роут вида :controller/:action/:id.
Давайте попробуем вызвать роут по правилам:
localhost:3000/magazines/random/1230492
Записи с таким ID не существует — но все работает! Так как мы в нашем методе не используем ID вообще — то для нас и не принципиально какую ерунду мы там напишем.
Давайте теперь все же попробуем сделать корректный роут вида localhost:3000/magazines/random/
Для этого существует опция :collection => < :action =>:HTTP_method >
Наш :action это :random, метод — :get
получаем

map.resources :magazines, :collection => < :random =>:get >

теперь все работает! =)

На этом вводная часть заканчивается. Дальше нас ждут более изощренные методы извращения ). Но не сегодня.
Спасибо, за потраченное на чтение статьи время ).

Источник

Rake Tutorial

Rake — инструмент для автоматизации сборки программного кода, написаный на Ruby, подобен таким инструментам как make, Ant или Phing. Хотя между ними существует огромная разница. В отличие от других инструментов, Rake не обеспечивает внешний DSL (например, XML-файл сборки в Ant). Вместо этого, все задачи описываются на чистом Ruby. Таким образом вы получаете полную гибкость и можете пользоваться полезными фичами Ruby.

Что такое инструменты сборки?

Если вы когда-либо пробовали инсталлировать программное обеспечение из исходных кодов в системе Linux или Unix, существует высокая вероятность, что вам приходилось иметь дело с make. Процесс установки обычно выглядит одинаково. Сперва вы переходите в директорию с уже распаковаными исходными кодами, затем вводите следующие команды:

./configure
make
make install

Вторая и третья линии — просто вызов программы make. В первую очередь при запуске make ищет файл Makefile. В нем содержится информация о исходниках и зависимостях между ними. make сортирует топологические зависимости и пытается решить их в надлежащем порядке. Это выглядит следующим образом: сначала разработчик указывает зависимости, а инструмент сборки отвечает за их обработку. make также позволяет сэкономить время. Если исходный код не изменился с последней компиляции, он не будет обработано снова, поскольку это будет чистой потерей времени. Инструменты сборки могут быть использованы не только для компиляции кода, хотя это и есть их основная задача. В общем, инструменты сборки используются для автоматизации утомительных и повторяющихся задач.

Отличия между Rake и остальными инструментами сборки.

Как я уже говорил, есть одно существенное различие между Rake и другими инструментами для сборки. Вместо того чтобы писать Makefile для make и build.xml для Ant и Phing, вы просто пишете код на Ruby. Вам не прийдется осваивать синтаксис новых инструментов сборки, если решите заменить один инструмент на другой.
Но теории недостаточно, давайте перейдем к практике.

Установка Rake

Установка rake достаточно легка, при условии, что у вас на компьюторе присудствуют Ruby gems. Для установки rake, введите следующие команды:

gem install rake

В большинстве случаев вам могут понадобиться права администратора, поэтому либо перейдите аод администратора, либо используйте приставку sudo.

sudo gem install rake

После того как rake gem установлен, мы можем написать наш первый пример.

Первый пример Rake

Наипростейший путь определить задачу Rake — написать следующий код на Ruby:

task :default do
puts «Hello World!»
end

Rake задачи должны всегда находиться в файле с именем Rakefile, Rakefile, rakefile.rb или Rakefile.rb. Первые две формы используются чаще всего. После того как Rakefile сохранен, нужно перейти в папку с этим файлом и выполнить следующую команду:

$ rake
(in /home/lukasz/ruby/rake_examples)
Hello World!

Первая rake задача работает отлично.

Итак, что же произошло на самом деле? Получая наш Rakefile, Rake ищет в нем задачи, которые являются просто вызовами метода task. В одном Rakefile может быть много задач. При запуске файла вы можете передать имя задачи, которую хотите выполнить. Если же задача не передается, rake ищет default задачу. Вот почему наш Rake вызов сделал свою работу без запросов каких-либо дополнительных параметров.

Давайте попробуем добавить много задач в один Rakefile:

task :ring do
puts «Bell is ringing.»
end

task :enter do
puts «Entering home!»
end

Если мы попробуем запустить команду rake без каких-либо параметров, то получим ошибку:

$ rake
(in /home/lukasz/ruby/rake_examples)
rake aborted!
Don’t know how to build task ‘default’

(See full trace by running task with —trace)

В этом файле не указано задание по умолчанию, поэтому мы должны явно передать им имя задачи:

$ rake enter
(in /home/lukasz/rake_examples)
Entering home!
$ rake ring
(in /home/lukasz/rake_examples)
Bell is ringing.

На первый взгляд наш пример отлично работает, но все же в код закралась ошибка, а именно, мы же не можем войти в дом, не позвонив в дверь. Здесь и начинаются зависимости.

Добавление зависимостей

Давайте немного модифицируем наш файл:

task :ring do
puts «Bell is ringing.»
end

task :enter => :ring do
puts «Entering home!»
end

Теперь, когда вы захотите зайти в дом, сначала произойдет звонок в дверь:

$ rake enter
(in /home/lukasz/ruby/rake_examples)
Bell is ringing.
Entering home!

Теперь Rake отвечает за звонок в дверь, перед тем как зайти. Вы можете объявить и более сложные зависимости и Rake будет отвечать за их решение. Вы просто указываете все что хотите и rake делает за вас всю нудную работу.

Хорошей новостью является то, что зависимость может быть указана не только при определении задачи, но и позже, в зависимости от выполнения условий времени. В конце концов, мы пишем задачи в языке программирования Ruby, а не статический файл XML, помните?

Для достижения того же эффекта со звонком в дверь, мы можем написать:

task :ring do
puts «Bell is ringing.»
end

task :enter do
puts «Entering home!»
end

task :enter => :ring

И эффект будет таким же.

Описание задачи.

Каждое задание, которое вы вы пишете, может быть описано с помощью нескольких простых слов. Описание будет служить вам не только встроеным комментарием, но также появится в списке доступных задач. Давайте добавим описания:

desc ‘Ring the bell’
task :ring do
puts «Bell is ringing.»
end

desc ‘Enter home’
task :enter => :ring do
puts «Entering home!»
end

Чтобы увидеть список доступных задач, запустите rake с параметром -Т или —tasks:

$ rake -T
(in /home/lukasz/ruby/rake_examples)
rake enter # Enter home
rake ring # Ring the bell

Как я уже сказал, инструменты сборки были сделаны с целью упрощения компиляции проекта. Есть много
зависимостей между отдельными файлами и Rake, так же как и многие инструменты сборки, поддерживает это. Это позволяет определить особый тип задач -a file task:

file ‘products.sql’ => ‘products.xml’ do
# build SQL INSERT clause and save it in products.sql file,
# basing on products.xml datafile
end

Файл задача — в общем — не отличается от регулярных задач. Дело в том, что он не будет работать, если входной файл (products.xml в данном случае) не существует. Он также не будет работать, если файл-результат (products.sql) не старше входного файла. Если вам не подходит данное поведение, тоесть вам нужно перезаписывать выходной файл каждый раз при запуске задачи, используйте регулярные задачи.

FileUtils

Rake включает в себя модуль Fileutil, который обеспечивает множество Unix-подобных методов, включая mkdir, rmdir, cp, chmod и touch.
Поскольку модуль Fileutils уже включен, вы можете вызывать эти методы непосредственно, без использования рамок операторов.

task :manipulate_files do
mkdir ‘new_dir’
mv ‘new_dir’, ‘lukasz’
chmod 0777, ‘lukasz’
touch ‘lukasz/wrobel.txt’
rm_rf ‘lukasz’
end

Если вы знакомы с командной оболочкой Linux / Unix вы освоите этот модуль в очень краткие сроки.
Кстати, помните поводение файлов-задач? Если выходной файл не старше входного файла, файл задача не будет работать. В случае, если вы хотите выполнить такую проверку в регулярных задачах, вы можете использовать метод Fileutils, который называется uptodate.

unless uptodate?(output_file, input_file)
# regenerate output_file
end
end

FileList

Представьте себе файл задачи, где объединены много входных файлов, чтобы получить один выходной файл. Наиболее очевидным способом определения зависимостей между файлами будет:

one_file_to_rule_them_all = ‘database.sql’
tables_sql = [‘orders.sql’, ‘payments.sql’, ‘categories.sql’]

file one_file_to_rule_them_all => tables_sql

Это будет работать, но что если мы создадим еще один входной SQL файл? Мы должны помнить о том, что его нужно добавить в наш список.

Не знаю как вы, а я немного запутался. Как уже говорилось, инструменты сборки были разработаны для автоматизации скучных и повторяющихся задач. А добавление файлов в наш список — это скучная задача. К счастью автор Rake тоже знал об этом.

Существует класс FileList, который может быть полезным в таких ситуациях. Давайте используем его сейчас:

Забудьте о добавлении каждого отдельного SQL файла в список. Rake сделает это за вас.

Аннотация

Существует огромное количество функций Rake, которые небыли охвачены в данном пояснении, например clean, clobber, rdoc и gem tasks, pathmap, rules и namespaces. У вас будет шанс узнать о них позже.
Я надеюсь что эта статья станет хорошей отправной точкой, чтобы получить представление о Rake. Rake доказал свою ценность и в настоящее время он широко используется в мире Ruby, так что написание Rake задач является обязательным навыком. Удачи в ваших собственных экспериментах с Rake.

Источник

Оцените статью