{"action":"created","comment":{"url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/comments/35131820","id":35131820,"diff_hunk":"@@ -0,0 +1,187 @@\n+#Active Record#\r\n+\r\n+##Введение##\r\n+\r\n+Вы здесь вероятно для того, чтобы изучать веб-разработку (а иначе… вы видимо ошиблись с выбором места…). Независимо от того, в чем ваша цель – создать собственный веб-сайт или начать карьеру веб-разработчика, самым важным навыком, который вы в итоге получите, является возможность мыслить логически и разбивать проблему на составляющие компоненты. После чего вы сможете обращаться к этим кусочкам по отдельности в разное время. В этом и заключается сущность проектирования и разработки.\r\n+\r\n+Возможно самая важная область при создании веб-сайта, где требуется логическое мышление, это правильное построение вашей модели данных. Данные - это основа почти всех крупных веб-приложений, от простого блога до сложнейшей сети данных Facebook. Невнятная или слишком усложненная модель данных может серьезно помешать, когда вы пытаетесь расти, и даже сделать вашу жизнь как разработчика чрезвычайно мучительной. Если вы работаете с неверными инструментами, что-то «простое» вроде запроса отобразить все комментарии, которые один пользователь оставил к сообщениям другого пользователя, может стоить вам слишком большого количества умственных усилий и циклов ЦПУ.\r\n+\r\n+Так как данные – это наиболее важная часть веб-приложения, вам должно быть очень интересно и то, как Rails взаимодействует с данными. К счастью, это одна из наиболее значимых вещей, которые Rails существенно улучшил по сравнению с опциями доступными всего несколько лет назад. Active Record – это интерфейс, предоставляемый Rails для взаимодействия между базой данных и вашим приложением. Он позволяет вам структурировать модели таких данных, как пользователи, сообщения в блогах, комментарии, последователи и др., причем осуществляется это очень логичным путем, очень похожим на простой английский язык. Если он покажется вам сложным (что иногда бывает), просто представьте себе жизнь до Active Record.\r\n+\r\n+Твердое понимание Active Record поможет вам сравнительно легко освоить оставшийся Rails. Вспомните, как несколько занятий назад Model в MVC была именно той частью, которая выполняет всю тяжелую работу. В этом уроке мы изучим основы работы с моделями от их установки до построения простых связей (ассоциаций?) между ними. Как обычно, предполагается, что материал будет рассматриваться на высоком уровне, а чтение предполагать достаточную глубину. Более продвинутые темы будут изучены в последующих уроках.\r\n+\r\n+##Вопросы для размышления##\r\n+\r\n+_Просмотрите их сейчас и после выполнения задания используйте их для самопроверки._\r\n+\r\n+* Что такое ORM?\r\n+\r\n+* Почему Active Record более удобен, чем использование SQL\r\n+\r\n+* Какие два шага необходимы для того, чтобы создать с помощью Active Record новую строчку в таблице вашей базы данных?\r\n+\r\n+* Что такое «генераторы» (generators) в Rails?\r\n+\r\n+\r\n+##Что такое ORM?##\r\n+\r\n+И все-таки что такое Active Record? Вспомните, что Rails – это на самом деле 7 пакетов (модулей? Gems) Ruby, которые гармонично работают вместе. Active Record – это, грубо говоря, пакет, который заботится обо всем, что связано с базами данных. А это и называется “ORM” .\r\n+\r\n+ORM расшифровывается как Object-Relational-Mapping (объектно-реляционное отображение). В сущности это обозначает, что Active Record берет данные, хранящиеся в строках и столбцах таблицы базы данных, которые должны быть модифицированы или возвращены с помощью SQL инструкций (если вы используете базу данных SQL), и позволяет вам взаимодействовать с этими данными так, будто это обычный Ruby объект.\r\n+\r\n+Таким образом, если я хочу получить массив, содержащий список всех пользователей, вместо написания кода по инициализации соединения с базой данных, а потом отправки запроса в виде чего-то вроде ``SELECT * FROM users``, и потом уже конвертации полученных результатов в массив, я просто пишу ``User.all`` и Active Record выдает мне массив, заполненный объектами User (пользователь) и я могу играть ими, как хочу. Вау!\r\n+\r\n+Еще более впечатляющим является то, что на самом деле не имеет никакого значения, каким типом базы данных вы пользуетесь (пока вы правильно задаете файл ``config/database.yml``), Active Record сглаживает все различия между базами данных так, что вам уже не надо об э том думать. Вы сосредотачиваетесь на написании кода приложения, а Active Record будет думать о мельчайших подробностях того, как соединить вас и вашу базу данных. Это также обозначает, что если вы переключаетесь с одной базы данных на другую, вам не нужно менять код любого крупного приложения, только некоторые конфигурационные файлы. Звучит логично, не так ли?\r\n+\r\n+##Модели Rails##\r\n+\r\n+Немного забежим вперед, потому что сначала имеет смысл подумать, какие отношения существуют между Rails и базой данных.  На самом деле, они достаточно очевидны – вы хотите сохранить информацию о пользователях, поэтому создаете таблицу базы данных, называемую ``users``. Вы хотите иметь доступ к данным из своего приложения, поэтому вы создаете модель ``User``, которая представляет собой Ruby файл, наследующий от Active Record и, следовательно, использующий все те удобные методы, которые я упоминал ранее (такие как ``all``, ``find``, ``create``). Одна таблица соответствует одной модели, которая наследует от Active Record.\r\n+\r\n+###30 секунд о работе между моделями###\r\n+\r\n+Если коротко, то Active Record позволяет вам создавать Ruby объект, который представляет собой строку в одной из таблиц базы данных, например ``User``. Создание нового User-a это процесс, состоящий из двух шагов. Во-первых, вам нужно сделать ``User.new``  и возможно передать ему кучу данных (hash) в виде атрибутов: \r\n+\r\n+     u = User.new(name: \"Sven\", email: \"sven@theodinproject.com\")\r\n+\r\n+Если вы не передаете данные (hash), тогда вам нужно будет вручную добавить атрибуты, задавая их как для любого другого Ruby объекта ``u.name = \"Sven\"``. Вторым шагом будет сохранение этого экземпляра модели в базу данных. До этого момента все это просто сидит в памяти и испарится, если вы ничего не будете с ним делать. Чтобы сохранить, просто вызовите ``u.save``. Вы можете одновременно осуществить оба шага, используя метод ``#create``:\r\n+\r\n+     u = User.create(name: \"Sven\", email: \"sven@theodinproject.com\")\r\n+\r\n+Это сохранит ваше время, но, как вы увидите позже, иногда вам захочется разделить их в своем приложении.\r\n+\r\n+###Ваше задание:###\r\n+\r\n+Это все было всего лишь вступлением на тему, что может делать Active Record. Дальше вы научитесь взаимодействовать с Active Record в ваших моделях.\r\n+\r\n+* Думаю, вы уже прочитали [Getting Started with Rails](http://guides.rubyonrails.org/getting_started.html) и сделали упражнение по созданию приложения из вводного раздела Rails Guides. Если еще нет, сделайте это!\r\n+\r\n+* Прочитайте раздел [Active Record Basics](http://guides.rubyonrails.org/active_record_basics.html) Rails Guides. \r\n+\r\n+* Более подробно Миграции и подтверждения (Migrations and Validations) мы изучим в следующем разделе и в уроке о функциях обратного вызова (Callbacks) позже в этом же курсе.\r\n+\r\n+* Файлы моделей (model files) в Rails находятся в папке ``app/models`` и являются обычными .rb файлами. Ключевой момент здесь это то, что имя класса дается по имени таблицы в вашей базе данных (но в ед.ч.), и этот класс наследует от Active Record::Base и получает его суперсилы.\r","path":"rails/13_active_record_basics.md","position":62,"original_position":62,"commit_id":"579dd3cf88339c6e2371ec4292a62938fab989b5","original_commit_id":"579dd3cf88339c6e2371ec4292a62938fab989b5","user":{"login":"vplrt","id":6698143,"avatar_url":"https://avatars.githubusercontent.com/u/6698143?v=3","gravatar_id":"","url":"https://api.github.com/users/vplrt","html_url":"https://github.com/vplrt","followers_url":"https://api.github.com/users/vplrt/followers","following_url":"https://api.github.com/users/vplrt/following{/other_user}","gists_url":"https://api.github.com/users/vplrt/gists{/gist_id}","starred_url":"https://api.github.com/users/vplrt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vplrt/subscriptions","organizations_url":"https://api.github.com/users/vplrt/orgs","repos_url":"https://api.github.com/users/vplrt/repos","events_url":"https://api.github.com/users/vplrt/events{/privacy}","received_events_url":"https://api.github.com/users/vplrt/received_events","type":"User","site_admin":false},"body":"этот класс наследует ActiveRecord::Base и получает его методы. (возможности)?","created_at":"2015-07-21T17:48:00Z","updated_at":"2015-07-21T17:48:00Z","html_url":"https://github.com/codenamecrud/curriculum/pull/68#discussion_r35131820","pull_request_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/68","_links":{"self":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/comments/35131820"},"html":{"href":"https://github.com/codenamecrud/curriculum/pull/68#discussion_r35131820"},"pull_request":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/68"}}},"pull_request":{"url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/68","id":40483054,"html_url":"https://github.com/codenamecrud/curriculum/pull/68","diff_url":"https://github.com/codenamecrud/curriculum/pull/68.diff","patch_url":"https://github.com/codenamecrud/curriculum/pull/68.patch","issue_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/68","number":68,"state":"open","locked":false,"title":"Active Record basics","user":{"login":"Mirnais","id":13438595,"avatar_url":"https://avatars.githubusercontent.com/u/13438595?v=3","gravatar_id":"","url":"https://api.github.com/users/Mirnais","html_url":"https://github.com/Mirnais","followers_url":"https://api.github.com/users/Mirnais/followers","following_url":"https://api.github.com/users/Mirnais/following{/other_user}","gists_url":"https://api.github.com/users/Mirnais/gists{/gist_id}","starred_url":"https://api.github.com/users/Mirnais/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Mirnais/subscriptions","organizations_url":"https://api.github.com/users/Mirnais/orgs","repos_url":"https://api.github.com/users/Mirnais/repos","events_url":"https://api.github.com/users/Mirnais/events{/privacy}","received_events_url":"https://api.github.com/users/Mirnais/received_events","type":"User","site_admin":false},"body":"First draft translation","created_at":"2015-07-21T17:30:22Z","updated_at":"2015-07-21T17:48:00Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2744ce4cdb88385cf1e1e5e447a84ec325eb4c52","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/68/commits","review_comments_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/68/comments","review_comment_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls/comments{/number}","comments_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/68/comments","statuses_url":"https://api.github.com/repos/codenamecrud/curriculum/statuses/579dd3cf88339c6e2371ec4292a62938fab989b5","head":{"label":"codenamecrud:active-record-basics","ref":"active-record-basics","sha":"579dd3cf88339c6e2371ec4292a62938fab989b5","user":{"login":"codenamecrud","id":11799719,"avatar_url":"https://avatars.githubusercontent.com/u/11799719?v=3","gravatar_id":"","url":"https://api.github.com/users/codenamecrud","html_url":"https://github.com/codenamecrud","followers_url":"https://api.github.com/users/codenamecrud/followers","following_url":"https://api.github.com/users/codenamecrud/following{/other_user}","gists_url":"https://api.github.com/users/codenamecrud/gists{/gist_id}","starred_url":"https://api.github.com/users/codenamecrud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenamecrud/subscriptions","organizations_url":"https://api.github.com/users/codenamecrud/orgs","repos_url":"https://api.github.com/users/codenamecrud/repos","events_url":"https://api.github.com/users/codenamecrud/events{/privacy}","received_events_url":"https://api.github.com/users/codenamecrud/received_events","type":"Organization","site_admin":false},"repo":{"id":33415384,"name":"curriculum","full_name":"codenamecrud/curriculum","owner":{"login":"codenamecrud","id":11799719,"avatar_url":"https://avatars.githubusercontent.com/u/11799719?v=3","gravatar_id":"","url":"https://api.github.com/users/codenamecrud","html_url":"https://github.com/codenamecrud","followers_url":"https://api.github.com/users/codenamecrud/followers","following_url":"https://api.github.com/users/codenamecrud/following{/other_user}","gists_url":"https://api.github.com/users/codenamecrud/gists{/gist_id}","starred_url":"https://api.github.com/users/codenamecrud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenamecrud/subscriptions","organizations_url":"https://api.github.com/users/codenamecrud/orgs","repos_url":"https://api.github.com/users/codenamecrud/repos","events_url":"https://api.github.com/users/codenamecrud/events{/privacy}","received_events_url":"https://api.github.com/users/codenamecrud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codenamecrud/curriculum","description":"Учебный план для codenamecrud.ru","fork":false,"url":"https://api.github.com/repos/codenamecrud/curriculum","forks_url":"https://api.github.com/repos/codenamecrud/curriculum/forks","keys_url":"https://api.github.com/repos/codenamecrud/curriculum/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codenamecrud/curriculum/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codenamecrud/curriculum/teams","hooks_url":"https://api.github.com/repos/codenamecrud/curriculum/hooks","issue_events_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/events{/number}","events_url":"https://api.github.com/repos/codenamecrud/curriculum/events","assignees_url":"https://api.github.com/repos/codenamecrud/curriculum/assignees{/user}","branches_url":"https://api.github.com/repos/codenamecrud/curriculum/branches{/branch}","tags_url":"https://api.github.com/repos/codenamecrud/curriculum/tags","blobs_url":"https://api.github.com/repos/codenamecrud/curriculum/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codenamecrud/curriculum/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codenamecrud/curriculum/git/refs{/sha}","trees_url":"https://api.github.com/repos/codenamecrud/curriculum/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codenamecrud/curriculum/statuses/{sha}","languages_url":"https://api.github.com/repos/codenamecrud/curriculum/languages","stargazers_url":"https://api.github.com/repos/codenamecrud/curriculum/stargazers","contributors_url":"https://api.github.com/repos/codenamecrud/curriculum/contributors","subscribers_url":"https://api.github.com/repos/codenamecrud/curriculum/subscribers","subscription_url":"https://api.github.com/repos/codenamecrud/curriculum/subscription","commits_url":"https://api.github.com/repos/codenamecrud/curriculum/commits{/sha}","git_commits_url":"https://api.github.com/repos/codenamecrud/curriculum/git/commits{/sha}","comments_url":"https://api.github.com/repos/codenamecrud/curriculum/comments{/number}","issue_comment_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/comments{/number}","contents_url":"https://api.github.com/repos/codenamecrud/curriculum/contents/{+path}","compare_url":"https://api.github.com/repos/codenamecrud/curriculum/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codenamecrud/curriculum/merges","archive_url":"https://api.github.com/repos/codenamecrud/curriculum/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codenamecrud/curriculum/downloads","issues_url":"https://api.github.com/repos/codenamecrud/curriculum/issues{/number}","pulls_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls{/number}","milestones_url":"https://api.github.com/repos/codenamecrud/curriculum/milestones{/number}","notifications_url":"https://api.github.com/repos/codenamecrud/curriculum/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codenamecrud/curriculum/labels{/name}","releases_url":"https://api.github.com/repos/codenamecrud/curriculum/releases{/id}","created_at":"2015-04-04T18:20:56Z","updated_at":"2015-07-09T19:32:32Z","pushed_at":"2015-07-21T17:38:33Z","git_url":"git://github.com/codenamecrud/curriculum.git","ssh_url":"git@github.com:codenamecrud/curriculum.git","clone_url":"https://github.com/codenamecrud/curriculum.git","svn_url":"https://github.com/codenamecrud/curriculum","homepage":"codenamecrud.ru","size":1329,"stargazers_count":2,"watchers_count":2,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":4,"forks":3,"open_issues":4,"watchers":2,"default_branch":"master"}},"base":{"label":"codenamecrud:master","ref":"master","sha":"2ed3543099eb3d2e8364dc0c7534d622c202ec74","user":{"login":"codenamecrud","id":11799719,"avatar_url":"https://avatars.githubusercontent.com/u/11799719?v=3","gravatar_id":"","url":"https://api.github.com/users/codenamecrud","html_url":"https://github.com/codenamecrud","followers_url":"https://api.github.com/users/codenamecrud/followers","following_url":"https://api.github.com/users/codenamecrud/following{/other_user}","gists_url":"https://api.github.com/users/codenamecrud/gists{/gist_id}","starred_url":"https://api.github.com/users/codenamecrud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenamecrud/subscriptions","organizations_url":"https://api.github.com/users/codenamecrud/orgs","repos_url":"https://api.github.com/users/codenamecrud/repos","events_url":"https://api.github.com/users/codenamecrud/events{/privacy}","received_events_url":"https://api.github.com/users/codenamecrud/received_events","type":"Organization","site_admin":false},"repo":{"id":33415384,"name":"curriculum","full_name":"codenamecrud/curriculum","owner":{"login":"codenamecrud","id":11799719,"avatar_url":"https://avatars.githubusercontent.com/u/11799719?v=3","gravatar_id":"","url":"https://api.github.com/users/codenamecrud","html_url":"https://github.com/codenamecrud","followers_url":"https://api.github.com/users/codenamecrud/followers","following_url":"https://api.github.com/users/codenamecrud/following{/other_user}","gists_url":"https://api.github.com/users/codenamecrud/gists{/gist_id}","starred_url":"https://api.github.com/users/codenamecrud/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/codenamecrud/subscriptions","organizations_url":"https://api.github.com/users/codenamecrud/orgs","repos_url":"https://api.github.com/users/codenamecrud/repos","events_url":"https://api.github.com/users/codenamecrud/events{/privacy}","received_events_url":"https://api.github.com/users/codenamecrud/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/codenamecrud/curriculum","description":"Учебный план для codenamecrud.ru","fork":false,"url":"https://api.github.com/repos/codenamecrud/curriculum","forks_url":"https://api.github.com/repos/codenamecrud/curriculum/forks","keys_url":"https://api.github.com/repos/codenamecrud/curriculum/keys{/key_id}","collaborators_url":"https://api.github.com/repos/codenamecrud/curriculum/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/codenamecrud/curriculum/teams","hooks_url":"https://api.github.com/repos/codenamecrud/curriculum/hooks","issue_events_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/events{/number}","events_url":"https://api.github.com/repos/codenamecrud/curriculum/events","assignees_url":"https://api.github.com/repos/codenamecrud/curriculum/assignees{/user}","branches_url":"https://api.github.com/repos/codenamecrud/curriculum/branches{/branch}","tags_url":"https://api.github.com/repos/codenamecrud/curriculum/tags","blobs_url":"https://api.github.com/repos/codenamecrud/curriculum/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/codenamecrud/curriculum/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/codenamecrud/curriculum/git/refs{/sha}","trees_url":"https://api.github.com/repos/codenamecrud/curriculum/git/trees{/sha}","statuses_url":"https://api.github.com/repos/codenamecrud/curriculum/statuses/{sha}","languages_url":"https://api.github.com/repos/codenamecrud/curriculum/languages","stargazers_url":"https://api.github.com/repos/codenamecrud/curriculum/stargazers","contributors_url":"https://api.github.com/repos/codenamecrud/curriculum/contributors","subscribers_url":"https://api.github.com/repos/codenamecrud/curriculum/subscribers","subscription_url":"https://api.github.com/repos/codenamecrud/curriculum/subscription","commits_url":"https://api.github.com/repos/codenamecrud/curriculum/commits{/sha}","git_commits_url":"https://api.github.com/repos/codenamecrud/curriculum/git/commits{/sha}","comments_url":"https://api.github.com/repos/codenamecrud/curriculum/comments{/number}","issue_comment_url":"https://api.github.com/repos/codenamecrud/curriculum/issues/comments{/number}","contents_url":"https://api.github.com/repos/codenamecrud/curriculum/contents/{+path}","compare_url":"https://api.github.com/repos/codenamecrud/curriculum/compare/{base}...{head}","merges_url":"https://api.github.com/repos/codenamecrud/curriculum/merges","archive_url":"https://api.github.com/repos/codenamecrud/curriculum/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/codenamecrud/curriculum/downloads","issues_url":"https://api.github.com/repos/codenamecrud/curriculum/issues{/number}","pulls_url":"https://api.github.com/repos/codenamecrud/curriculum/pulls{/number}","milestones_url":"https://api.github.com/repos/codenamecrud/curriculum/milestones{/number}","notifications_url":"https://api.github.com/repos/codenamecrud/curriculum/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/codenamecrud/curriculum/labels{/name}","releases_url":"https://api.github.com/repos/codenamecrud/curriculum/releases{/id}","created_at":"2015-04-04T18:20:56Z","updated_at":"2015-07-09T19:32:32Z","pushed_at":"2015-07-21T17:38:33Z","git_url":"git://github.com/codenamecrud/curriculum.git","ssh_url":"git@github.com:codenamecrud/curriculum.git","clone_url":"https://github.com/codenamecrud/curriculum.git","svn_url":"https://github.com/codenamecrud/curriculum","homepage":"codenamecrud.ru","size":1329,"stargazers_count":2,"watchers_count":2,"language":null,"has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"open_issues_count":4,"forks":3,"open_issues":4,"watchers":2,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/68"},"html":{"href":"https://github.com/codenamecrud/curriculum/pull/68"},"issue":{"href":"https://api.github.com/repos/codenamecrud/curriculum/issues/68"},"comments":{"href":"https://api.github.com/repos/codenamecrud/curriculum/issues/68/comments"},"review_comments":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/68/comments"},"review_comment":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/codenamecrud/curriculum/pulls/68/commits"},"statuses":{"href":"https://api.github.com/repos/codenamecrud/curriculum/statuses/579dd3cf88339c6e2371ec4292a62938fab989b5"}}}}