Комментарии 76
Извиняюсь за минус, мискликнул в Vimium.
Объясните мне кто-нибудь пожалуйста, зачем авторы Руби так сильно пропагандируют идею монки патчинга? Как-бы, в остальных языках это считают смертным грехом, а здесь всё наоборот.
Ещё среди минусов я бы лично записал то, что RoR не умеет соединяться более чем с одной базой данных. Столько хвалёных отзывов — а такой простой штуки, которая есть, наверное, на любом PHP фреймворке — не сделали.
Ещё документация к Laravel, например, — намного более качественная, чем для рельс… У рельс и документации-то в общем-то и нет толком, есть лишь набор "инструкций", которые объясняют, как сделать то или иное дело на рельсах. Но это всё-таки немного другое, не документация.
Ещё я бы записал в минусы Ruby любовь к "размазыванию" классов на кучу файлов. Ну, это тоже частично на тему монки патчинга.
В общем, по итогам своей работы в последние пару лет, я всё также использую Laravel в своих проектах, и в общем-то более чем доволен им.
Ещё среди минусов я бы лично записал то, что RoR не умеет соединяться более чем с одной базой данных.
Для этих целей есть не очень живой db-charmer (До Rails 3 включительно) и воплне живой octopus (есть поддержка Rails 4)
Ещё среди минусов я бы лично записал то, что RoR не умеет соединяться более чем с одной базой данных. Столько хвалёных отзывов — а такой простой штуки, которая есть, наверное, на любом PHP фреймворке — не сделали.
ActiveRecord по дефолту умеет подключаться к нескольким БД (docs).
Ещё документация к Laravel, например, — намного более качественная, чем для рельс… У рельс и документации-то в общем-то и нет толком, есть лишь набор "инструкций", которые объясняют, как сделать то или иное дело на рельсах. Но это всё-таки немного другое, не документация.
Документация тоже вполне ок, "набор инструкций" это в гайдах.
Ещё я бы записал в минусы Ruby любовь к "размазыванию" классов на кучу файлов. Ну, это тоже частично на тему монки патчинга.
Ни разу не видел чтобы в нормальном приложении класс "размазывался" на несколько файлов.
Да, насчёт ActiveRecord я ошибся, прошу прощения.
По документации уже написал чуть ниже.
Насчёт последнего — в общем-то, всё дело в монки патчах, которые накладываются друг на друга разными библиотеками, что, в целом, вообще неправильно. Эта тема подробно была описана одним из руби-разработчиков, перевод статьи есть на хабре. Хотя, из комментов к этой же статье, я так понял, что для руби уже реализовали механизм Refinements. В этом свете, хотелось бы узнать, насколько активно его стали применять на практике в разработе рельсов и других библиотек, и действительно ли этот механизм полностью решает проблему конфликтов при монки патчах.
Ни разу не видел чтобы в нормальном приложении класс "размазывался" на несколько файлов.
A Вы код самого Rails смотрели? Тот же ActiveRecord::Base — просто гигантский класс, размазанный на десятки файлов внутри самого фреймворка и ещё сотни файлов из сторонних гемов расширяют его же.
class A
...
end
ActiveRecord::Base — просто гигантский класс, размазанный на десятки файлов
Да, но он состоит из более-менее логичных модулей.
сотни файлов из сторонних гемов расширяют его же.
это другой вопрос.
Но для обоих этих случаев есть документация, в самом приложении такого быть не должно.
Что Вы имеете в виду?
В самом приложении не должно быть Rails или гемов, расширяющих существующие классы?
Или если Вы выносите такие случаи в гемы — то это ok, а вот если в коде самого приложения — то это фу? Это ж двоемыслие какое-то...
Расширять существующие классы вообще не ок. Ни в своем прилжении, ни в гемах. Но, к сожалению, это есть.
По поводу того, что сам класс разбит на много файлов — он разбит с помощью модулей. Я изначально подумал что в 10 файлах переоткрыт класс и дописаны методы. Да, модули в принципе то же самое, но они хотя бы могут иметь логику разбиения.
А чтобы у вас была возможность подключить любой из этих десятков файлов отдельно в свой «Plain Old Object». ActiveRecord::Base всего лишь делает это за вас подключая всё.
Также никто вас так же не заставляет использовать всякий DSL который накинет вам модулей в классы (те же вызовы rolify, devise еще чего-нибудь) все можно подключать отдельно. Заинклюдте все руками. Невозможного нет ничего.
P.S. Да иногда есть гемы которые написаны криво, ну так помогите сообществу, сделайте pull request.
А человек был в неведении, что в любом Rails-приложении есть десятки классов, размазанных на несколько файлов.
По другому можно делать, но это грести против сообщества. Поэтому 'любовь к «размазыванию» классов на кучу файлов' — это факт, имеющий место в Ruby-сообществе. Поэтому странно видеть утверждения, что приложение, в котором это встречается, априори ненормальное.
Справедливости ради, в рельсах можно работать более чем с одной базой данных. К примеру, если модель SomeModel лежит в другой БД, достаточно написать:
class SomeModel < ActiveRecord::Base
establish_connection "another_db_#{Rails.env}"
...
end
и добавить соответствующие записи в config/database.yml
. Ну или можно использовать concern — что универсальнее. Примерно так же можно использовать прямые запросы к разным базам.Документация к рельсам — вам мало guides.rubyonrails.org, api.rubyonrails.org, apidock.com? Куда уж больше-то?
С классами тоже имхо все в порядке — если не размазывать их специально, а соблюдать структуру. Каждый класс, каждый модуль выполняют определенную функцию. Или это плевок в сторону MVC в целом?
В-общем, по итогам своей работы за последние пару лет, я практически полностью перешел на Rails в своих проектах, и более чем доволен им :)
Нет, вовсе не плевок. По большей части, я задал вопрос чтобы увидеть адекватные ответы. Спасибо за ссылки и разъяснения, посмотрю на досуге.
Или это плевок в сторону MVC в целом?
Меня тут больше расстраивает использование этой триады в контексте рельсов. Ну то есть еще до рельсов существовал MVC, и еще до рельсов был придуман mediating controller MVC. И вот MVC в рельсах совсем не то значит.
И на волне популярности рельсов вот это "немного не то" насктолько распространилось, что сейчас проще просто отказаться от использования этой аббривиатуры целиком и полностью ибо она потеряла свой смысл…
Сейчас львиная доля бэкэнд разработчиков считают что MVC это когда логика манипуляции сущностями в контроллерах. Это примерно тот же уровень урона для начинающих как UML концентрирующий внимание разработчиков на классы а не на взаимодействие объектов.
правильное с вашей точки зрения понимание MVC
И вот тут сложность. Проблема в том что все они правильны, просто они разные и для разных задач. Различия заключаются в том как эти M, V и C взаимодействуют друг с другом. Аббривиатура из названий элементов никак не может это показать.
Например в smalltalk MVC (оригинальное MVC если хотите) подразумевалось что View представляет собой полноценный объект реализующий активное представление. Оно подписывается на события модели и обновляет само себя, полностью отвечая за реализацию GUI. Ну и в те времена это все же подразумевало много кода для работы с GUI.
Контроллеры же подписывались на события контролов UI (например клик по кнопке, ввод данных в текстовое поле) и вызывали методы приложения. Поток данных шел ровно по кругу, никаких двусторонних взаимодействий. Ну и опять же View могло быть несколько на скрин, можно было делать композицию элементов и т.д. То есть это не "архитектура" а просто "шаблон проектирования", который описывает кусочек системы в очень маленьком масштабе.
Со временем появились полноценные UI фреймворки, сегодня вон вообще декларативное представление в моде и необходимость в активных вьюшках пропала. Да и тот факт что и view и controller зависили от модели слегка повышали связанность. В итоге перешли к использованию MVP и подобных подходов, где вся вьюшка стала пассивной и логика из нее вытекла в контроллер, который начал называться презентер. Теперь за управление и взаимодействие с UI стал отвечать один компонент. Это существенно упростило дело. Схожую проблему в мелкософте решили при помощи MVVM, которая ввела концепцию биндингов. Ну и куча разных вариантов еще появилась.
В RoR же MVC намного ближе к Model-View-Adapter по схеме взаимодействия. Однако разделение ответственности не такое явное, но для решения задач этого достаточно.
То есть проблема не в самом MVC или не в том как RoR интерпритирует эти три буквы, а в людях, которые начинают думать что в принципе есть единственное правильное MVC.
Пропаганды не видел, скорее про это пишут в смысле "даже так вот можно". Сам же манки патчинг довольно удобен, особенно сейчас, когда очень много OSS. Часто либа может иметь баг или просто не иметь поддержки нужного функционала, которая решается добавлением пары строчек. Часто такие штуки фичи не нужны всем, только в одном приложении. В этой ситуации есть несколько решений:
- сделать PR, и ждать когда примут и зарелизят,
- форкнуть либу, и потом периодически рибэйзить на апстрим,
- сделать манки патч, и пользоваться оригиналом.
Конечно, в зависимости от количества изменений 1й и 2й варианты могут быть предпочтительны. Но по мне 3й варинат лучше, если правок действительно немного. И манки патчинг в руби удобен (в жс вон что люди придумывают: https://github.com/jhnns/rewire).
Ну и плюс во время разработки. Можно проверить локально, переопределив сначала методы, проверить. А затем вернуться к 1му/2му варианту.
Вы всё-таки не правы, честно. К сожалению, как я вижу, на деле манки патчи используют повсеместно в Ruby-сообществе, и это именно считается нормальной практикой, которая в том числе и пропагандируется.
Почитайте хотя-бы этот комментарий ниже, почитайте эту статью о монки патчах, ссылку на которую я уже давал здесь же. В ней достаточно хорошо рассказано о том, как обстоят дела с этой техникой.
По сути, меня подобное довольно странное отношение к коду и остановило от перехода с всеми унижаемого PHP на Ruby в своё время. Вы меня извините, но в PHP вообще такое невозможно, чтобы два разных модуля вдруг каким-то образом вызвали конфликт друг у друга. Мне просто приятнее и спокойнее использовать тот инструмент, поведение которого я могу контролировать в большей степени.
И ваш пример со ссылкой на JS-библиотеку для изменения кода для тестов тоже не очень-то годится в качестве довода. Одно дело в тестах создавать заглушки — и совсем другое дело писать основной код приложения подобным образом.
* Ruby/Rails никуда не уходят, до сих пор адекватный инструмент решения многих задач. Конкурентов особо нет. Впрочем, пик развития недавно прошел.
Цитата из статьи:
> Ruby перестает быть модным, но продолжает быть эффективным инструментом для построения стартапов
* Go никаким боком не конкурент хотя часто используется совместно — для нагруженных участков
* Многие опытные разработчики сейчас переходят с рельс на Elixir/Phoenix (сюрприз, написанные людьми из команды рельс — с исправлением накопленных за годы развития косяков).
Например, www.safaribooksonline.com/library/view/advanced-rails/9780596510329/ch04s04.html
Документация отличная, с учетом версий, например: apidock.com/rails/ActiveRecord/Base
Спасибо за первую ссылку. Да, мои знания устарели, прошу прощения, тут видимо я явно ошибся.
Но насчёт второго. Ну, неплохо, да. Но всё-таки, посмотрите как удобно сделали документацию к Laravel. Я ожидал увидеть для рельсов что-то подобное, но когда изучал их, то из официальных данных нашёл только гайды (про них я уже писал — это не совсем документация, эти гайды объясняют основы, но не объясняют тонкости).
Насчет документации, я считаю, в рельсах она лучше по удобству, например можно сравнить 1 в 1 laravel.com/api/5.2/Illuminate/Database.html и apidock.com/rails/ActiveRecord/Base.
А если охота доку как в Ларе, то можно глянуть и на hanamirb.org/guides/getting-started, таки одними рельсами руби комьюнити не заканчивается.
Цитата:
This is the official documentation site for RSpec. Much of the documentation you see here is
written with Cucumber, which, like RSpec, provides executable documentation. The
Cucumber features you see here have all been run against RSpec's codebase, serving as
specification, documentation and regression tests of the behavior.
P.S. Напомню, что Cucumber тоже родился в недрах рубишного сообщества.
При работе с рельсами go to definition и автокомплит уже далеки от совершенства и читать доки и SO приходится в разы чаще. Помогает, но частично:
* Использование аннотаций
* Дебаг
* Rails console
Подскажите, как кто решает проблему поддержки Rails в IDE?
Хочешь узнать где находишься? в дебаггере show-method, хочешь узнать что хранится в сущности? ls ApplicationController и так далее. Это просто другой подход, скорее всего непривычный для тех кто сидел на IDE и особенно на языках со строгой типизацией. Магия дебажится, вот хорошая статья на эту тему: http://www.schneems.com/2016/01/25/ruby-debugging-magic-cheat-sheet.html
Зато многие неявные вещи зачастую страхуют от косяков. Для обратных случаев есть тесты на все вокруг. Как можно писать проект без нормального тестового покрытия мне например уже не понятно.
Справедливости ради разработчики той же Symfony фигачат все в textmate и довольны. На самом деле и без автокомлита можно с этим фреймворком работать эффективно (то есть нет дурацких AbstractFactoryFactory), просто с ним удобнее.
Поэтому я до сих пор приверженец старого доброго TextMate 2 (для ruby у меня набралось много сниппетов и команд) в связке с постоянно запущенным pry в консоли и не парюсь по этому поводу.
Кстати на счет последнего, подозреваю, что для Руби там тоже все ок.
В vim, emacs или где-то еще можно перейти к определению метода в геме? Я пока видел только в рубимайне. Когда-то думали перейти в что-то другое, но без этой фичи это не вариант.
В случае других языков можно с ycmd (для rust, js, ts, python, c, c++), но ruby в нём пока не поддерживается. Для ruby может заработать eclim.
Это автодополнение. Я имею ввиду что когда есть написанный код, можно клацнуть по методу и перейти к его объявлению. Да, это не всегда показывает правильный метод или показывает 10 вариантов, но это невероятно удобно.
Не беспокойтесь, я знаю что такое go to definition.
Тот же ycmd для rust у меня даёт и автодополнение (полноценное, в автодополнении доступны методы соответствующих типажей, реализуемых объектом), так и go to definition (в том числе и в исходники самого rust'а). Вообще go to definition для динамических языков или при использовании AOP — крайне сложная вещь (учитывая, например, monkey patches, использование method_missing, define_method и прочее метапрограммирование). IDE для тех же RoR часто анализируют описанную в коде схему базы, чтобы дать автодополнение для findby, select и прочих.
Что умеет eclim для динамических языков — не знаю, не использовал. Просто предположил что ядро эклипса может давать результат, сравнимый с тем, что дают продукты jetbrains.
И, да, я пробовал TextMate-подобную, там что-то не все работало как хотелось, возможно это были кеймапы 1-ой версии. Я было начал исправлять под себя, но потом понял, что у меня нету столько времени с ним ковыряться.
Гем pry (debbie — тот же при, только с набором расширений), может очень помочь. Я без show-method, show-doc теперь как без рук.
От Python, извините, воротит. Мне он кажется неудобным и даже в какой-то мере некрасивым.
Что не очень нравится в Ruby, похоже он все-таки относительно медленный. Делал конвертер больших json файлов в csv, написался он быстро, а вот выполнялся чуть ли не часы. После опыта написания подобных вещей на перле такого не ожидаешь.
Просто отказаться от гемов сложно, удобство ruby во многом в том, что почти всегда можно найти гем, решающий тот или иной кейс, но многие из них имеют эту дурную привычку — без спроса расширить что-нибудь глобальное.
Я считаю, что эту проблему мог бы решить некий манифест, пропагандирующий разработчикам гемов использовать меньше магии на момент загрузки зависимостей, а их пользователям — не лениться вручную включать нужные модули в свои классы.
А так, хоть я и наблюдаю у ruby кучу недостатков, некоторые из которых реально раздражают, но все равно пытаю к этому языку нежные чувства. Сам использую его не только в web-приложениях, но и в различных консольных утилит как для автоматизации рабочих моментов, так и просто для фана (как-то раз ну очень захотелось консольный генератор гитарных аккордов — накодил его за полдня).
Но без фанатизма: если что-то вырастает из ruby или изначально не подходит для разработки на нем, тогда уже используются другие языки. Например, я бы не стал писать на ruby WebSocket-сервис, обрабатывающий множество долгих запросов (в теории можно JRuby). Поэтому не понимаю нахера
Еще молодой.
Слежу за ним с интересом.
Если будет развиваться/расти — можно будет программировать с привычным синтаксисом Ruby и использовать быстрый компилируемый язык программирования.
С виду развивается в нужном направлении. Все менее смахивает на Ruby, но не вызывает отторжение.
При грамотном пиаре ждет светлое будущее.
Поигравшись с Kemal-ом (по образу синатры), несложный API или простенькие сайтики уже можно городить. При запуске не ест ни память, ни процессор. Деплой тоже «несколько проще» рельсового.
К предыдущему посту про ActionCable в пятых рельсах — те же мысли возникли. Веб-сокеты на Kemal-е выглядят аккуратнее.
Не испытываю никаких проблем с сопровождением проектов на Ruby on Rails. Все достаточно логично и удобно.
Проекты предпочитаю писать «с нуля» и по возможности самостоятельно реализовывать механизмы, по минимуму используя сторонние библиотеки — мне интересно программировать, и доставляет удовольствие разработка (кстати, именно программирование на Ruby с удовольствием). При этом все получается легко, быстро и качественно.
Тем, кто прочит закат и «смерть» Ruby, могу посоветовать только одно — не нравится вам (а, скорее, не получается) — ну и не обращайте внимания — для вас Ruby даже и не появлялся на свет. И не надо пинять на зеркало, коли… ну отойди ты от зеркала — не мучай изображение! )))
Ну вот, уже MVC из Rails называют классическим.
И в целом с точки зрения модели все хорошо:
- СУБД — деталь реализации модели и мы о них можем вообще не говорить.
- модели могут инкапсулировать в себе другие модели (то есть в качестве модели может выступать любой объект, который в своб очередь работает с другими моделями).
- модели активны. То есть управление состоянием это задача модели, а контроллеры могут только просить что-то сделать. Точно так же представление может подписываться на события и обновлять само себя но вот тут я не уверен...
Насколько я помню в rails таки использует пассивные вьюшки, что превращает "классический MVC" в mediating-controller MVC. Что уже как бы не "классическое". Но это даже хорошо. Хотя если я тут не прав — буду рад если меня кто-нибудь подправит.
Никто вам не запрещает сделать так <%= User.first.name %>
Никто не запрещает но это не ок. Это как лесть в шаблонах в базу данных. Отсутствие разделения ответственности.
где модель полностью обособлена и общается с View только через адаптер( контроллер ).
так так оно по сути чаще всего и происходит. Адаптер забирает данные и заполняет данными пассивное view. Можно сделать view активной но это не приветствуется насколько я понимаю.
- активная вьюшка, то есть какой-то объект который выделяется на соединение по WebSocket и предоставляет какое-то представление данных клиенту.
- Контроллер ничего не знает о view. То есть он максимум может подписаться на события из объекта вьюшки и обрабатывать асинхронные действия пользователей конвертируя их в синхронные сообщения моделям.
- Модель активна и предоставляет события для view
Вот в таком ключе соглашусь что можно использовать smalltalk MVC 1979-ого года выпуска. Но мы в таком случае сильно усложняем все так как взаимодействие между клиентом и сервером становится нифига не stateless.
Тут не может быть MVA потому что View имеет ссылку на Model.
View именно имеет ссылку на Model или ее дает контроллер? В классическом MVC да, модель является зависимостью View (причем обязательной зависимостью) и ничего не знает о контролере. А если мы передаем во view модель (как это сделано в большинстве фреймворков которые называют себя MVC) то там вместо модели может быть любой другой объект предоставляющий состояние. И тогда как бы… все взаимодействие так или иначе проходит через адаптер (контроллер).
Я так понимаю вы вообще Rails в глаза не видели если задаете такие вопросы?
Я пытаюсь добиться полного взаимопонимания. В коммерческой разработке RoR не использовал (я же похапэшник), только для самообразования. А вопросы я задаю просто для того что бы понять, об одном и том же мы говорим или нет.
Модель можно вызвать без участия контроллера, ничего никуда не нужно передавать, просто вызываете прямо во View.
Это просто глобальный доступ к состоянию. Разница не большая. Это не делает вьюшку активной, это просто слегка ломает разделение ответственности. Вьюшка может даже не докадываться что это модель, это может быть что угодно. Так что прямого взаимодействия view и модели не закладывалось.
Вызвав модель во View вы уже подписались на цикл событий модели WebSocket тут не обязателен.
В рамках request/response модели выполнения (stateless апишки) не должно быть цикла событий модели, вьюшка тупо забирает текущее состояние и на этом все.
Модель независима как от контроллера так и от View.
Именно так, но только вот контроллер знает о View. Вот в чем соль. Именно контроллер решает какое view использовать. А стало быть мы можем говорить о том что мы имеем дело именно с Model-View-Adapter.
Судить об оригинальной smalltalk MVC 1979 можно лишь относительно, как и притянуть её реалии к современному веб приложению.
Нет, весь спор разгорелся только из-за того что вы назвали "архитектуру MVC" в RoR классической. И это вводит в заблуждение так как есть "более классическая" версия. Я бы согласился если бы вы сказали что RoR реализует классическую MVC Model2, но по факту все это лишь MVA которую используют почти все бэкэнд фреймворки вне зависимости от языка.
И на этом закончим наше обсуждения, до момента как вы испробуете Rails в реальном разработке.
Спор на самом деле пустой. Он всего-лишь подтверждает что лучше вообще не использовать MVC как название подхода, просто потому что оно сильно привязано к контексту. А Rails использовать я не хочу, во всяком случае сейчас.
И после этого ты получаешь минус скорее всего от самого судьи комментатора.
Я вас не минусовал если вы переживаете. И причин минусовать тоже не вижу.
Иногда поражаешься с людей не использовали инструмент в работе, и судят что там и как.
Я достаточно работал с RoR что бы понимать как там что. И я не говорил о том что там что-то плохо, для своих задач там все весьма грамотно. Я просто придрался к словам "классический MVC".
p.s. Laravel я тоже не использую в коммерческой разработке.
На момент создание фреймворка не было технологии позволяющей оповещать реалтайм со стороны бекенда фронтенд и активно перерисовывать View.
Long Polling уже давно был. Задолго до вебсокетов.
Ну и опять же, был, например, JSF, и в нём можно было сделать MVC очень похожий на классический.
Рельсы просто перепутали понятия, а народ подхватил.
Классической реализацией концепции MVC принято считать версию именно с активной моделью.
Да. И это прежде всего такая модель, которая оповещает о своих изменениях всех подписчиков. View сами подписываются на нужные observable события модели и при изменении сами обновляются. Обычно используется паттерн Observer.
Тогда назревает вопрос, если в Rails не классическое MVC то какое по вашему?
1) Модели по-настоящему активны: они содержат бизнес-логику, позволяют подписываться на их изменения и оповещают всех подписчиков, когда эти изменения происходят.
2) View тоже более активны: содержат логику представления, сами знают, как себя отрисовать, подписываются на нужные модели и отображают их данные. Когда модель оповещает об изменениях, вьюхи сами перерисовывают себя.
3) Controller обрабатывает действия пользователя, которые он совершает во View (обычно, это нажатие кнопочек) и вызывает соответствующие методы модели. Это просто клей, связывающий события из View с методами моделей.
В итоге получается, что-то вроде модного нынче Flux. Поток данных преимущественно идёт в одном направлении: пользователь что-то жмёт, контроллер вызывает метод модели, модель "пересчитывается" и оповещает о своём новом состоянии всех подписчиков (т.е. View), представления обновляются в соответствии с новыми данными из модели и пользователь видит эти изменения. Схема такая:
User -> Controller
^ |
| v
View <- Model
Разумеется, в рамках серверного рендера HTML и протокола HTTP реализовать подобное без Long Polling трудно.
В рельсах же используется MVP, эдакая адаптация MVC под мир веба. Тут всё проходит через контроллер: контроллер реагирует на действие пользователя, обращается к модели, получает из неё данные для отображения, получает нужное представление и рендерит это представление с данными из модели. Тут схема несколько другая:
User <-> Controller <-> View
^
v
Model
И непонятно по какой причине, авторы рельс назвали это MVC. Вот с тех пор все и путаются.
К слову, в JSF можно было легко организовать MVC куда более приближенное к классическому.
Почему? Почему COBOL?
Ruby перестает быть моднымПо-моему наоборот, Ruby сейчас на пике моды… Появляются курсы типа «Врубиться в Ruby. Научим кодить с нуля». Люди далёкие от программирования начинают интересоваться как освоить Rails. В общем, настолько моден, что невольно вспоминается байка про банкира и чистильщика обуви.
История языков программирования: о прошлом, настоящем и будущем Ruby