Я изучаю руководство по началу работы с Rails и запутался в разделе 6.7. После генерации скаффолда я нахожу следующий автоматически сгенерированный блок в моем контроллере:
def index
@posts = Post.all
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @posts }
end
end
Я хотел бы понять, как на самом деле работает блок response_to. Какой тип переменной является форматом? Являются ли методы .html и .json объекта формата? Документация для
ActionController::MimeResponds::ClassMethods::respond_to
не отвечает на вопрос.
ruby-on-rails
капуста
источник
источник
format.html
- без аргументов), он будет использовать условные обозначения (основанные на URL и глаголе HTTP), чтобы выбрать представление (ожидается, что это HTML). Респондент (формат) здесь проинструктирован отображать URL-адреса, заканчивающиеся на .json, путем сериализации в json вместо использования представлений и соглашений.Ответы:
Я новичок в Ruby и застрял в этом же коде. Части, на которые я повесил трубку, были немного более фундаментальными, чем некоторые из ответов, которые я нашел здесь. Это может или не может помочь кому-то.
respond_to
это метод на суперклассActionController
.do
доend
, с|format|
в качестве аргумента блока.format
аргумент.http://api.rubyonrails.org/v4.1/classes/ActionController/Responder.html
Responder
Не содержит метод.html
или.json
, но мы называем эти методы так или иначе! Эта часть бросила меня в петлю.method_missing
. Если вы вызываете метод, который не существует (например,json
илиhtml
), Ruby вызываетmethod_missing
метод вместо этого.http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html
Responder
Класс использует вmethod_missing
качестве своего рода регистрации. Когда мы вызываем json, мы говорим ему отвечать на запросы с расширением .json путем сериализации в json. Нам нужно вызыватьhtml
без аргументов, чтобы сказать, что он должен обрабатывать .html-запросы способом по умолчанию (используя соглашения и представления).Это можно записать так (с использованием JS-подобного псевдокода):
Эта часть смутила меня. Я все еще нахожу это не интуитивным. Руби, кажется, использует эту технику совсем немного. Весь class (
responder
) становится реализацией метода. Для использованияmethod_missing
нам нужен экземпляр класса, поэтому мы обязаны передать обратный вызов, в который они передают объект, подобный методу. Для кого-то, кто кодировал на C-подобных языках в течение 20 лет, это очень отсталый и не интуитивный для меня. Не то чтобы это плохо! Но это то, что многим людям с таким происхождением нужно подумать, и я думаю, что это может быть после ОП.PS обратите внимание, что в RoR 4.2
respond_to
был извлечен в ответ респондентов драгоценный камень.источник
method_missing
, учитывая, что вы можете передать ей аргументы и блок!respond_to
в контроллерах, без гема респондентов в Gemfile. Возможно, немного о том,respond_to
чтобы быть извлеченным в жемчужину респондентов, было изменено?Это блок кода Ruby, который использует вспомогательный метод Rails. Если вы еще не знакомы с блоками, вы часто их увидите в Ruby.
respond_to
является вспомогательным методом Rails, который присоединен к классу Controller (точнее, к его суперклассу). Он ссылается на ответ, который будет отправлен в представление (которое отправляется в браузер).Блок в вашем примере - это форматирование данных - путем передачи параметра «format» в блоке - для отправки из контроллера в представление всякий раз, когда браузер запрашивает данные html или json.
Если вы находитесь на своем локальном компьютере, и у вас настроена почтовая платформа Post, вы можете перейти на
http://localhost:3000/posts
страницу и увидите все свои сообщения в формате html. Но, если вы введете это:,http://localhost:3000/posts.json
тогда вы увидите все свои сообщения в объекте json, отправленном с сервера.Это очень удобно для создания тяжелых приложений на javascript, которые должны передавать json назад и вперед с сервера. Если вы хотите, вы можете легко создать json api на своей стороне рельсов и передавать только одно представление - как представление индекса вашего контроллера Post. Затем вы можете использовать библиотеку javascript, такую как Jquery или Backbone (или обе), чтобы манипулировать данными и создавать свой собственный интерфейс. Они называются асинхронными пользовательскими интерфейсами и становятся очень популярными (Gmail - один из них). Они очень быстрые и дают конечному пользователю более настольный опыт в Интернете. Конечно, это только одно из преимуществ форматирования ваших данных.
Способ написания Rails 3 был бы таким:
Поместив
respond_to :html, :xml, :json
верхнюю часть класса, вы можете объявить все форматы, которые вы хотите, чтобы ваш контроллер отправлял вашим представлениям.Затем в методе контроллера все, что вам нужно сделать, это response_with (@whwhat_object_you_have)
Это просто упрощает ваш код немного больше, чем то, что автоматически генерирует Rails.
Если вы хотите узнать о внутренней работе этого ...
Из того, что я понимаю, Rails анализирует объекты, чтобы определить, каким будет фактический формат. Значение переменных 'format' основано на этом самоанализе. Rails может многое сделать с небольшим количеством информации. Вы будете удивлены тем, как далеко зайдет простой @post или: post.
Например, если у меня был частичный файл _user.html.erb, который выглядел так:
_user.html.erb
Затем, только это в моем представлении индекса позволит Rails знать, что ему нужно найти частичную часть «users» и выполнить итерацию по всем объектам «users»:
index.html.erb
позволит Rails узнать, что ему нужно найти частичку 'user' и выполнить итерацию по всем объектам 'users':
Вы можете найти этот пост полезным: http://archives.ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with
Вы также можете просмотреть источник: https://github.com/rails/rails
источник
respond_to
иrespond_with
введен? Я использую рельсы 2.3.5 и получаюNoMethodError (undefined method respond_to)
Из того, что я знаю, response_to - это метод, прикрепленный к ActionController, так что вы можете использовать его в каждом отдельном контроллере, потому что все они наследуются от ActionController. Вот метод Rails response_to:
Вы передаете ему блок , как я показываю здесь:
| Формат | part - это аргумент, который ожидает блок, поэтому внутри метода response_to мы можем это использовать. Как?
Что ж, если вы заметили, мы передаем блок с префиксом & в методе response_to, и мы делаем это для обработки этого блока как Proc. Поскольку аргумент имеет «.xml», «.html», мы можем использовать его как вызываемые методы.
Что мы в основном делаем в классе response_to, так это вызываем методы ".html, .xml, .json" для экземпляра класса Responder.
источник
Чтобы понять, что к чему
format
, вы можете сначала взглянуть на источникrespond_to
, но быстро вы обнаружите, что на самом деле вам нужно взглянуть на код для retrieve_response_from_mimes .Отсюда вы увидите, что блок, который был передан
respond_to
(в вашем коде), фактически вызывается и передается с экземпляром Collector (на который внутри блока ссылаются какformat
). Collector в основном генерирует методы (я полагаю, при запуске Rails), основываясь на том, что знают rails- типы mime .Так, да,
.html
и.json
методы , определенные (во время выполнения) на коллектор ( так называемыйformat
класс).источник
Метапрограммирование за регистрацией респондента (см. Ответ Parched Squid) также позволяет вам делать такие полезные вещи, как это:
Строка csv будет вызывать to_csv для каждого сообщения, когда вы посещаете /posts.csv. Это позволяет легко экспортировать данные как CSV (или любой другой формат) с вашего сайта rails.
Строка js будет вызывать / выполнять файл javascript /posts.js (или /posts.js.coffee). Я обнаружил, что это простой способ создания сайта с поддержкой Ajax с использованием всплывающих окон пользовательского интерфейса jQuery.
источник
От java POV, формат представляет собой реализацию анонимного интерфейса. Этот интерфейс имеет один метод, названный для каждого типа MIME. Когда вы вызываете один из этих методов (передавая ему блок), то, если rails чувствует, что пользователь хочет этот тип контента, тогда он вызовет ваш блок.
Конечно, изюминка в том, что этот анонимный объект клея на самом деле не реализует интерфейс - он динамически перехватывает вызовы метода и работает, если это имя типа mime, о котором он знает.
Лично я думаю, что это выглядит странно: блок, который вы передаете, выполняется . Для меня было бы больше смысла передавать в хэш меток формата и блоков. Но, похоже, именно так все и сделано в RoR.
источник
Это немного устарело, Райан Бигг делает большую работу, объясняя это здесь:
http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to
На самом деле, это может быть немного больше деталей, чем вы искали. Как оказалось, за кулисами происходит много всего, в том числе необходимо понять, как загружаются типы MIME.
источник
«Формат» - это ваш тип ответа. Например, может быть json или html. Это формат вывода, который получит ваш посетитель.
источник
Есть еще одна вещь, о которой вы должны знать - MIME.
Если вам нужно использовать тип MIME, и он не поддерживается по умолчанию, вы можете зарегистрировать свои собственные обработчики в config / initializers / mime_types.rb:
Mime::Type.register "text/markdown", :markdown
источник