Правильная работа с ActiveRecord

июля 21, 2012  |  Published in Model, Ruby on Rails, Ruby on Rails 3

Статья будет иметь несколько хаотичной. В ней я приведу несколько примеров того, что я считаю неправильной работой с ActiveRecord. Что-то в статье — истина последней инстанции, а что-то — субъективное и, возможно, ошибочное мнение автора. Статья ориентирована на тех, кто хоть немного знаком с Ruby on Rails.

Очень популярная ошибка — не использование limit(1) для выборки одиночной записи с использованием where и других методов Quering API. Суть ошибки в том, что Rails не может за вас подумать о том, что вам необходима одна единственная запись, а не все удовлетворяющие условию. В случае, когда вы не используете limit(1) будет выполняться поиск по всей таблице, а не только до первой соответствующей условию записи.

Word.where(word: 'cat')
# Word Load (0.9ms) SELECT "words".* FROM "words" WHERE "words"."word" = 'cat'
# => [records]

Word.where(word: 'cat').limit(1)
# Word Load (0.7ms) SELECT "words".* FROM "words" WHERE "words"."word" = 'cat' LIMIT 1
# => [record]

UPD Вообще не пользуйтесь .limit(1), вместо .limit(1) используйте first, если вам действительно необходим лишь один элемент. Дело в том, что limit(1) возвращает массив с одним единственным элементом, чтобы получить этот элемент нам необходимо вызывать еще один метод — first (Array#first), или обращаться к элементу через индекс — Model.limit(1)[0].

Tag.limit(1).first
# Tag Load (1.6ms)  SELECT "tags".* FROM "tags" LIMIT 1

Tag.first
# Tag Load (0.8ms)  SELECT "tags".* FROM "tags" LIMIT 1

Read the rest of this entry »

Tags: , , ,

Ruby on Rails 3: Ассоциации между моделями ч. 2

апреля 26, 2012  |  Published in Ruby on Rails, Ruby on Rails 3, Базы данных

ruby on rails tutorial Ассоциации между моделями ч. 1. В этой статьи мы поговорим об интересных параметрах и возможностях ассоциаций моделей.

Псевдонимы

Часто бывает необходимо или желательно использовать отличное от имени модели имя ассоциации. Например у нас есть две модели Store и User и у Store имеется владелец (seller — продавец). store.user выглядит не очень красиво, как буд-то речь идет о пользователе магазина, а не о его владельце (продавце), кроме того, у нас может быть несколько ассоциаций с моделью User, например у нас может быть buyer и seller.
Read the rest of this entry »

Tags: , , ,

Ruby on Rails 3: Ассоциации между моделями ч. 1

апреля 5, 2012  |  Published in Ruby on Rails, Ruby on Rails 3, Базы данных

ruby on rails tutorial Ассоциации между моделями ч. 2. Экземпляры моделей представляют собой сущности реального мира, а ассоциации между ними являются ни чем иным как отношениями этих сущностей между собой.

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

 belongs_to — принадлежность другой модели. Пример:

 

class Post < ActiveRecord::Base
  belongs_to :category
end

Read the rest of this entry »

Tags: , , ,

Ruby on Rails 3: Основы работы с ActiveRecord моделью

февраля 10, 2012  |  Published in Ruby on Rails, Ruby on Rails 3, Базы данных

ruby on rails tutorialRubyDev — ваш друг в изучении Ruby и Rails!

Что такое модель?

Модель — это составляющая часть архитектурного паттерна MVC, которая хранит бизнес логику. В вашем приложении все модели должны храниться в директории app/models в отдельных файлах, имена которых должны соответствовать имени модели, например: Post -> post.rb, InvoiceProduct -> invoice_product.rb.

Как связаны модель и таблица?
В большинстве случаев модель ассоциируется с определенной таблицей в базе данных, например модель Post будет ассоциироваться с таблицей posts. Экземпляр модели являет собой объект представляющий одну запись из таблицы, а сама модель (класс) используется для работы со всей таблицей, например для поиска всех записей соответствующих некоторому условию.

Обратите внимание на то, как называется модель и как называется соответствующая ей таблица. Имя модели — всегда в едином числе, а имя таблицы во множественном.

Как создать модель?
Создать модель можно вручную, но лично я предпочитаю использовать генератор моделей:

$ rails g model Product name:string description:text price:integer
      invoke  active_record
      create    db/migrate/20120210115708_create_products.rb
      create    app/models/product.rb
      invoke    test_unit
      create      test/unit/product_test.rb
      create      test/fixtures/products.yml

Вызывая генератор я передаю в него в качестве аргументов имя модели и имена полей таблицы ассоциируемой с моделью вместе с типами данных этих полей (столбцов).

Генератор модели мне кажется более удобным потому, что одной командой я создаю сразу все необходимые для работы файлы: собственно модель, миграцию для создания соответствующей модели таблицы в БД, файл фикстур и болванку для написания тестов.
Read the rest of this entry »

Tags: , , , , , , ,

Ruby on Rails 3: Миграции в Rails 3.x

февраля 9, 2012  |  Published in Ruby on Rails, Ruby on Rails 3

ruby on rails tutorialRubyDev — ваш друг в изучении Ruby и Rails!

Миграции — это очень удобный инструмент для управления структурой базы данных без использования SQL.

Как работают миграции?

Миграции — это обыкновенные классы, которые наследуются от ActiveRecord::Migration, описывают структуру базы данных и хранятся в директории db/migrate/ вашего проекта.  При использовании генератора scaffold или генератора моделей автоматически будет создан и класс миграции для создания соответствующей модели таблицы.

$ rails g model Post title:string content:text

В результате помимо создания самой модели будет создан еще и файл миграции следующего содержимого:

#db/migrate/20120126202608_create_posts.rb
class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.string :title
      t.text   :content

      t.timestamps
    end
  end
end

В предыдущих версиях Rails использовались методы self.up и self.down для соответственно выполнения и отката миграции. В Rails 3.1, как показано выше используется один единственный метод change вместо self.up и self.down. Методы up и down также доступны, но в большинстве случаев достаточно метода change.

Для выполнения миграций необходимо выполнить команду:

$ rake db:migrate

Запуск этой команды выполнит все имеющиеся миграции, что ранее не были выполнены. Read the rest of this entry »

Tags: , , , , ,

Ruby on Rails 3: Введение в ActiveRecord

февраля 9, 2012  |  Published in Ruby on Rails, Ruby on Rails 3

ruby on rails tutorialRubyDev — ваш друг в изучении Ruby и Rails!

В этой главе вы узнаете более подробно о том, что такое модель, чем занимается ActiveRecord входящий в состав Ruby on Rails, что такое ORM и что такое миграции.

Что такое модель?

Из предыдуших глав или из своего опыта разаботки на других языках программирования и платформах вы уже должно быть знаете, что такое модель, но я вынужден повториться:

Модель — это часть приложения, которая непосредственно работает с данными, то есть хранит бизнес-логику приложения.

В Ruby on Rails модельная прослойка реализована в виде модуля ActiveRecord. ActiveRecord предоставляет паттерн ORM для работы с записями в базе данных и не только ORM.

Что такое ORM?

ORM (Object Relation Mapping) — паттерн проектирования, который сводится к достаточно простой вещи — представлению записей в виде объектов.

Что такое ActiveRecord?

ActiveRecord — это фреймворк для работы с реляционными базами данных (MySQL, PostgreSQL, SQLite и т.д.). ActiveRecord реализует в себе не только паттерн ORM, но и миграции, валидацию, обратные вызовы (коллбеки), паттерн «Наблюдатель», ассоциации между записями и много-много чего еще.

В приложении на Ruby on Rails модели хранятся в директории app/models вашего приложения в файлах, что носят имена соответствующие именам классов-моделей: Post -> app/models/post.rb.

Модель в случае использования ActiveRecord представляет собой класс наследуемый от класса — интерфейса ActiveRecord::Base, например:

class Post < ActiveRecord::Base
end

Приведенный выше пример модели наследуясь от класса ActiveRecord::Base наследует от него всю мощь ActiveRecord, по этому приведенные выше две строки кода уже умеют делать очень многое!

Что такое миграции?

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

Миграции очень удобны для создания и редактирования и управления структурой базы данных. Миграции позволяют абстрагироваться от базы данных и использовать код написанный на изящном Ruby для определения схемы базы данных. Кроме того миграции упрощают разворачивание вашего проекта на сервере и позволяют всего одной командой создать все необходимые для работы приложения таблицы в базе данных.

 

Лучшая благодарность автору — ваши комментарии и популяризация ресурса! Спасибо всем за внимание к проекту и моральную поддержку его автора. Не забывайте о нашей группе во Вконтакте: !

Tags: , , , , ,

Заполнение базы данных тестовыми данными при помощи seed-fu

декабря 24, 2011  |  Published in Ruby on Rails, Тестирование

Я отношусь к тойкасте людей, что не воспринимают интеграционные тесты. Программа не может оценить внешний вид приложения так, как то может сделать человек. По этой причине я предпочитаю сам смотреть на то, как выглядит приложение. Для того, чтобы это изучение приложения было максимально приближена к реальности — необходимо заполнять базу тестовыми данными, кроме того, тестовые данные необходимы для тестирования производительности приложения на «реальных» данных. В Rails имеется встроенный механизм seed-ирования базы данных, однако он мне не очень нравится и в этой статье я рассказывать о нем не буду. Вместо встроенного функционала я предпочитаю использовать seed-fu — отличное решение поставляемое в виде совсем обыкновенного gem’а, которое делает заполнение БД тестовыми данными более удобным.
Read the rest of this entry »

Tags: , , ,

RDR3R: Callbacks (коллбеки — обратные вызовы) в Rails

октября 5, 2011  |  Published in Ruby on Rails, Ruby on Rails 3

Callbacks — колбеки (обратные вызовы) — это вызов методов как реакция на какое-нибудь действие объекта. Коллбеки привязываются к определенным методом и могут быть выполнены до или после вызова метода к которому они прикреплены. Например, когда в Rails вы используете ассоциацию с зависимостью, например такую:

Post has_many :comments, :dependent => :destroy

То после действия destroy для объекта — записи запускается соответствующий after_destroy коллбек, который выполняет удаление всех принадлежащищ Post’у комментариев.

В Rails существуют коллбеки модели и колбеки контроллеров, в Sinatra (Rack) существуют коллбеки обработчиков запроса, даже в RSpec существуют коллбеки before и after для подготовки и удаления данных для спецификаций.
Read the rest of this entry »

Tags: , , ,

RDR3R > Single Table Inheritance (STI) в Rails 3

июля 26, 2011  |  Published in Ruby on Rails, Ruby on Rails 3

Пришло мне тут два письма с просьбой написать о STI — наследовании от одной таблицы. Материал достаточно простой, однако, если люди просят — почему не уделить написанию статьи пол часика?

Признаться честно, мне не нравится термин STI применительно к Rails, поскольку на самом деле наследуются не таблицы, а классы. Здесь больше подходит термин Class Table Inheritance поскольку один класс наследуясь от другого получает доступ к таблице основного класса.

Разберемся с терминами.

Базовый класс — это класс от которого наследуются все остальные классы.

Наследуемый класс — здесь все понятно.

Для чего необходимо STI? — STI достаточно удобная штука и используется в двух основных случаях:

1. У нас имеются две и более моделей, которые имеют абсолютно одинаковые атрибуты, но должны вести себя по разному.

2. У нас имеются две и более моделей, которые имеют несколько общих атрибутов, общие атрибуты выносятся в отдельную таблицу и отдельную модель — базовый класс.

Read the rest of this entry »

Tags: , , ,

Обратимые миграции в Rails 3.1

мая 10, 2011  |  Published in Ruby on Rails, Ruby on Rails 3, Базы данных

Миграции всегда были одной из основных «фишек» Ruby on Rails. В Rails 3.1 миграции приобретают еще один козырь, который упрощает процесс поддержки логики в up и down методах миграции. Если вам нужно немного восстановить свои знания о миграциях, я рекомендую прочитать официальный .

Давайте начнем с разбора примера миграции из Rails 3.0:

#db/migrate/20110505090317_create_posts.rb
class CreatePosts < ActiveRecord::Migration
  def self.up
    create_table :posts do |t|
      t.string :title
      t.text :body

      t.timestamps
    end
  end

  def self.down
    drop_table :posts
  end
end

Эта миграция создает в базе данных таблицу posts с двумя полями — title и body тип хранимых данных в которых соответственно string и text. Хэлпер timestamps создает поля типа datetime — created_at и updated_at. Для отката этой миграции нам просто необходимо удалить таблицу posts. Метод .down как раз и занимается откатом миграции — удалением таблицы posts. Когда Rails использует миграцию, миграция запускает метод .up. Для отката миграции (которая выполняется командой rake db:rollback) миграция выполняет метод .down.

Глядя на эту миграцию возникают два вопроса:

- Почему именно методы класса, вместо методов экземпляра класса?
- Для простых случаев почему бы не объявить только метод выполнения миграции и защитить миграцию от отката?

Замечательный человек Аарон Петерсон думает так же и решил упросить миграции.
Read the rest of this entry »

Tags: , ,