FeaturesPluginsDocs & SupportCommunityPartners

Формирование связей между моделями Rails

Составитель Брайан Леонард (Brian Leonard), редактор Гэйл Чаппелл (Gail Chappell)
Декабрь 2007 г.
[номер версии: V6.0-3]

Это руководство посвящено формированию связей ("один к одному" и "один ко многим") между моделями в проектах Ruby on Rails в среде NetBeans.

Содержание

Содержимое на этой странице относится к среде IDE NetBeans 6.0

Для работы с этим руководством требуется следующее программное обеспечение.

Программное обеспечение или ресурс Требуемая версия
Среда IDE NetBeans с поддержкой Ruby и Rails Версия 6.0
Сервер базы данных MySQL Версия 5.0
Инфраструктура Rails 1.2.5*

* Настоящее руководство, написанное для Rails 1.2.5, задействует функцию создания базового интерфейса. Поскольку в Rails 2.0 создание базового интерфейса не поддерживается, следовать указаниям этого руководства при использовании Rails 2.0 невозможно.

Создание демонстрационной базы данных

Это руководство основано на руководстве Создание блога на Ruby за 10 минут. По завершении работы с этим руководством можно запустить проект, созданный в ходе изучения, и перейти к следующему разделу. В противном случае загрузите файл RubyWebLog.zip и следуйте указаниям по созданию демонстрационной базы данных.

Примечание: В настоящем руководстве используется сервер базы данных MySQL. Сведения об использовании сервера базы данных MySQL в приложении на Ruby приведены в статье Установка и настройка поддержки Ruby. В этой статье также описывается использование сервера базы данных Java DB вместо MySQL.

  1. Откройте окно ввода команд.
  2. Запустите сервер базы данных MySQL, если он еще не запущен.
  3. Введите следующую команду для создания базы данных разработки и нажмите клавишу Enter.
    mysqladmin -u root -p create rubyweblog_development

    Примечание: Если пароль для пользователя root не установлен, опустите аргумент -p.

  4. Откройте проект "rubyweblog" в среде IDE.

    Примечание: При первом создании или открытии проекта Ruby в среде IDE производится проверка на наличие других установленных версий Ruby кроме пакета JRuby, входящего в комплект поставки. Если такие версии установлены, на экран выводится диалоговое окно для выбора программного обеспечения, которое будет использоваться. Если требуется использовать встроенный интерпретатор JRuby, выберите "JRuby"; при необходимости использования собственной установленной версии Ruby выберите эту версию. Дополнительные сведения приведены в разделе Настройка среды IDE для использования собственной установленной версии Ruby в руководстве "Установка и настройка Ruby".

  5. Если для работы с базой данных требуется пароль, внесите изменения в файл database.yml и укажите пароль (password) в настройках разработки. Сохраните файл.

    Для быстрого доступа к файлу database.yml нажмите комбинацию клавиш Alt+Shift+O (Ctrl+Shift+O для компьютеров Макинтош), введите database.yml в текстовом поле "File Name" и нажмите клавишу Enter.
  6. Щелкните правой кнопкой мыши узел "rubyweblog" и выберите "Migrate Database > To Current Version".

    В результате этого действия в базу данных добавляется таблица "posts", а затем поле "body". Ход процесса переноса отображается в окне "Output".
  7. Запустите приложение и создайте новое сообщение.

Создание модели "Comment"

Настоящее руководство посвящено расширению проекта "rubyweblog" путем реализации возможности добавления читателями комментариев к сообщениям. Сначала необходимо создать модель "Comment" для хранения экземпляров комментариев читателей. В проект уже входит модель "Post" для хранения сообщений блога.

  1. В окне "Projects" разверните узел "rubyweblog", если он еще не раскрыт, и щелкните правой кнопкой мыши узел "Models", где выберите "Generate".

  2. Введите Comment post_id:integer created_at:datetime comment:text в поле "Arguments" и нажмите кнопку "OK".

    Rails Generator создает модель с именем "Comment". В эту модель входят следующие файлы:

    • app/models/comment.rb. Файл, содержащий методы для модели "Comment". Этот файл открывается в области изменения.
    • test/unit/comment_test.rb. Модульный тест для проверки модели.
    • test/fixtures/comments.yml. Тестовый элемент для заполнения модели.
    • db/migrate/migrate/003_create_comments.rb. Файл переноса для изменения структуры базы данных. Версия этого файла – 003, поскольку в проекте уже имеются два файла переноса – 001_create_posts.rb и 002_add_body.rb, создающие и модифицирующие таблицу "posts".

Перенос базы данных

Следующий требующий обработки файл – это файл переноса 003_create_comments.rb.

  1. В окне "Output" щелкните ссылку на файл 003_create_comments.rb.

    В открывшемся файле содержится метод "self.up", создающий таблицу "comments", и метод "self.down", уничтожающий таблицу "comments", как показано в следующем примере кода:

    class CreateComments < ActiveRecord::Migration
      def self.up
        create_table :comments do |t|
          t.column :post_id, :integer
          t.column :created_at, :datetime
          t.column :comment, :text
        end
      end
    
      def self.down
        drop_table :comments
      end
    end
    В результате переноса создается таблица комментариев с четырьмя полями: id (целое число), post_id (целое число), created_at (дата и время) и comment (текстовое описание).
  2. Щелкните правой кнопкой мыши узел "rubyweblog" и выберите "Migrate Database > To Current Version".

    В результате этого действия в базу данных добавляется таблица "comments". Ход процесса переноса отображается в окне "Output".

Определение связи между моделями "Post" и "Comment"

Теперь в приложении две модели: модель "Post", создающая новое сообщение в блоге, и модель "Comment", добавляющая к сообщению в блоге новый комментарий. На этом этапе между этими двумя моделями устанавливается связь, причем комментарий связывается с единственным сообщением, а в сообщении может содержаться несколько комментариев.

  1. Разверните узел "Models" и откройте post.rb.
  2. Добавьте следующую связь has_many в post.rb:

    class Post < ActiveRecord::Base
      validates_presence_of :title, :body
      has_many :comments
    end

    Метод has_many указывает, что с сообщением может быть связано ноль, один или более комментариев.

    Введите триггер hm и нажмите клавишу Tab: триггер разворачивается в шаблон кода has_many :objects.

  3. Откройте "Models > comment.rb" и добавьте связь belongs_to:

    class Comment < ActiveRecord::Base
      belongs_to :post
    end

    Метод belongs_to указывает, что комментарий может быть связан только с одним сообщением. По умолчанию в ActiveRecord для связи комментария с сообщением с соответствующим post.id используется post_id.

    Триггер bt раскрывается в belongs_to :object.

Изменение базового интерфейса контроллера

Теперь обратимся к контроллеру blog_controller.rb, который обеспечивает базовый интерфейс для создания, чтения, обновления и удаления сообщений в блоге.

  1. Разверните узел "Controllers" и откройте blog_controller.rb.

    В контроллере имеются все действия для создания базового интерфейса, в т.ч. index, list, show, new, create, edit, update и destroy.
  2. Измените действие show, как показано в следующем примере кода, для сохранения идентификатора "post_id" во флэш:

    def show
      @post = Post.find(params[:id])
      flash[:post_id] = @post.id
    end
    Код выполняет поиск сообщения, связанного с параметром id, переданным вместе с запросом. Затем параметр id помещается во флэш для дальнейшего использования. Флэш подобен сеансу HTTP, но для одного запроса. При помещении данных во флэш они становятся доступными для следующего запроса, но после этого удаляются (отсюда термин "флэш").
  3. Выполните прокрутку до конца файла blog_controller.rb и добавьте следующее действие post_comment перед последним оператором end:

    def post_comment
        @comment = Comment.new(
          "post_id" => flash[:post_id],
          "created_at" => Time.now,
          "comment" => params[:comment]['comment']
          )
          if @comment.save
            flash[:notice] = 'Comment was successfully added.'
            redirect_to :action => 'show', :id => flash[:post_id]
          end
    end

    Действие post_comment вызывается при нажатии кнопки "Post" для отправки комментария. Первый блок кода получает из флэша идентификатор post_id (например, 1, 2 или больше), который используется для поиска сообщения блога, связанного с этим идентификатором id. Затем создается новый объект "Comment", связанный с этим post_id, также состоящим из времени создания и собственно комментария. Параметры, полученные от страницы, передаются архитектурой Rails в виде хэша (параметры[:комментарий]), из которого в результате работы кода извлекаются параметры комментария (параметры[:комментарий]['комментарий']).

    "Comment" представляет собой класс ActiveRecord, так что при вызове его метода "save" запись комментария сохраняется в базе данных. Затем сообщение помещается во флэш. Код вызывает действие show, загружающее страницу show.rhtml. На этой странице перезагружаются все комментарии, в т.ч. новый комментарий.

Изменение представления для добавления комментариев

На этом этапе изменяется файл show.rhtml, используемый для вывода отдельного сообщения блога.

  1. Выберите "Views > blog" и откройте файл show.rhtml.
  2. Добавьте следующий код в конце файла show.rhtml.

    <hr>
    <h4>Comments</h4>
    
    <% form_tag :action  => 'post_comment' do %>
       <p><label for="comment_comment">Comment</label><br/>
       <%= text_area 'comment', 'comment' %></p>
       <%= submit_tag "Post" %>
    <%end %>
    В результате работы этого кода создается форма, в которую входит поле ввода текста для написания комментария и кнопка отправки запроса "Post", как показано на следующем рисунке. При отправке формы вызывается действие post_comment.
  3. Сохраните файлы и запустите приложение.
  4. Перейдите по ссылке "Permalink" для просмотра подробных данных сообщения в блоге. Попробуйте добавить комментарий в текстовой области; следует отметить, однако, что в блоге пока не отображаются комментарии по нажатии кнопки "Post".

    Если отправка сообщения проходит успешно, в верхней части экрана выводится сообщение, как показано на следующем рисунке. На следующих этапах добавляется код для сбора и вывода комментариев.

    Вид модели "Comment" без комментариев

Отображение комментариев

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

  1. Перейдите к действию blog_controller.rb в коде show и вставьте следующую переменную экземпляра post_comments для сбора комментариев:

    def show
        @post = Post.find(params[:id])
        @post_comments = @post.comments.collect
        flash[:post_id] = @post.id
    end
    Поскольку к модели "Post" была добавлена связь has_many :comments, доступ ко всем комментариям сообщения осуществляется вызовом @post.comments.
  2. Скопируйте и вставьте в файл show.rhtml содержимое от следующего тега <ul> до строки <h4>Comments</h4> включительно:

    <ul>
    <% @post_comments.each do |comment| %>
    <li><%= h comment.comment %><br>
      <div style="color: #999; font-size: 8pt">
          Posted on <%= comment.created_at.strftime("%B %d, %Y at %I:%M %p") %>
      </div>
    </li>
    <% end %>
    </ul>
    
    
    В результате работы этого кода к комментариям применяется стиль, они выводятся в виде маркированного списка, и добавляется дата и время создания комментария.
  3. Выберите "File > Save All", затем обновите страницу в обозревателе.

    Комментарии в блоге теперь выводятся в виде маркированного списка, как показано на следующем рисунке.

    Рис. 2: Вид модели "Comment" с комментариями

Что дальше?

>> Дополнительная документация по Ruby в среде NetBeans


Bookmark this page

del.icio.us furl simpy slashdot technorati digg
Companion
Projects:
MySQL Database Server   Open JDK: an Open SourceJDK   GlassFish Community: an Open Source Application Server    Mobile & Embedded Community    Open Solaris   java.net - The Source for Java Technology Collaboration   Virtual Box - full virtualizer  Open ESB - The Open Enterprise Service Bus Powered by