рельсы 3 леса реляционной модели - PullRequest
14 голосов
/ 22 марта 2011

Существуют ли какие-либо учебные пособия по созданию простой модели, использующей отношения «многие ко многим»?

Ответы [ 2 ]

45 голосов
/ 22 марта 2011

Этот шаг я написал при создании нижеприведенного testapp, используя ruby ​​1.9.2 на Rails 3.0.5. Также смотрите 'Gemfile' для драгоценных камней, которые я использовал (весь загружаемый Testapp, ссылка в конце в части 15). Итак, вот так:

1) перейдите в место, где вы хотите создать тестовое приложение, затем

rails new mynewtestapp
cd mynewtestapp

2) затем добавьте 2 модели, имеющие ассоциацию has_and_belongs_to_many

rails g scaffold book title:string author:string
rails g scaffold user name:string age:integer

3) затем вам нужно создать объединительную таблицу для этой ассоциации ... по умолчанию rails будет искать таблицу с именем, состоящим из имен обеих связанных таблиц в алфавитном порядке ... поэтому давайте создадим миграцию в создать такую ​​таблицу

rails g migration createBooksUsers

4) открыть сгенерированный файл миграции, который на данный момент выглядит как

class CreateBooksUsers < ActiveRecord::Migration
  def self.up
  end

  def self.down
  end
end

5) изменить это, чтобы выглядеть так

class CreateBooksUsers < ActiveRecord::Migration
  def self.up
    create_table :books_users, :id => false do |t|
      t.integer :book_id
      t.integer :user_id
    end
  end

  def self.down
    drop_table :books_users
  end
end

6) добавить ассоциацию has_and_belongs_to_many к модели книги и пользователя, а также новые идентификаторы, добавленные отношением

приложение / модель / book.rb

class Book < ActiveRecord::Base
  attr_accessible :title, :author, :user_ids
  has_and_belongs_to_many :users
end

приложение / модель / user.rb

class User < ActiveRecord::Base
  attr_accessible: :name, :age, :book_ids
  has_and_belongs_to_many :books
end

7) теперь наши модели и миграции завершены ... давайте создадим таблицы

rake db:create
rake db:migrate

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

8) теперь решите, какой объект должен быть назначен какому объекту .... конечно, вы можете сделать это обоими способами ... я сделаю это простым и покажу это одному ... допустим, у вас есть только мало пользователей и хотят назначить их в книги ...

на данный момент, я бы сказал, давайте получим некоторую помощь извне, например, предложенный бинарный x ... но для простоты я бы выбрал гем simple_form вместо Formtastic. Я думаю, у каждого есть свои любимые ... но simple_form, кажется, дает вам больше свободы в CSS-стилизации всего вывода под ваши пожелания ... поэтому давайте установим simple_form на этом этапе, просто сделайте

echo "gem 'simple_form', :git => 'git://github.com/plataformatec/simple_form.git'" >> Gemfile

, чтобы добавить simple_form в ваш Gemfile, а затем запустить

bundle install

и установите простую форму в свое приложение (т.е. создайте конфигурацию, стили по умолчанию и языковые файлы) с помощью

rails g simple_form:install

9) время изменить форму наших книг

форма книги прямо сейчас должна выглядеть следующим образом

приложение / просмотров / книги / _form.html.erb

01    <%= form_for(@book) do |f| %>
02      <% if @book.errors.any? %>
03        <div id="error_explanation">
04          <h2><%= pluralize(@book.errors.count, "error") %> prohibited this book from being saved:</h2>
05    
06          <ul>
07          <% @book.errors.full_messages.each do |msg| %>
08            <li><%= msg %></li>
09          <% end %>
10          </ul>
11        </div>
12      <% end %>
13    
14      <div class="field">
15        <%= f.label :title %><br />
16        <%= f.text_field :title %>
17      </div>
18      <div class="field">
19        <%= f.label :author %><br />
20        <%= f.text_field :author %>
21      </div>
22      <div class="actions">
23        <%= f.submit %>
24      </div>
25    <% end %>

Используя simple_form, мы можем просто заменить часть приведенного выше кода (строки 1 и 14-24), чтобы весь файл выглядел так:

01    <%= simple_form_for(@book) do |f| %>
02      <% if @book.errors.any? %>
03        <div id="error_explanation">
04          <h2><%= pluralize(@book.errors.count, "error") %> prohibited this book from being saved:</h2>
05    
06          <ul>
07          <% @book.errors.full_messages.each do |msg| %>
08            <li><%= msg %></li>
09          <% end %>
10          </ul>
11        </div>
12      <% end %>
13    
14      <%= f.input :title %>
15      <%= f.input :author %>
16      <%= f.association :users %>
17    
18      <%= f.button :submit %>
19    
20    <% end %>

10) Теперь вы можете запустить приложение

rails s

добавьте некоторых пользователей, затем добавьте книгу, и появится ваша первая форма has_and_belongs_to_many: first simple_form form without special effects

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

public/stylesheets/simple_form.css

и вставьте в него следующие строки

/* public/stylesheets/simple_form.css */
.simple_form label {
  float: left;
  width: 100px;
  text-align: right;
  margin: 2px 10px;
}

.simple_form div.input {
  margin-bottom: 10px;
}

.simple_form div.boolean, .simple_form input[type='submit'] {
  margin-left: 120px;
}

.simple_form div.boolean label, .simple_form label.collection_radio, .simple_form label.collection_check_boxes{
  float: none;
  margin: 0;
}

.simple_form .error {
  clear: left;
  margin-left: 120px;
  font-size: 12px;
  color: #D00;
  display: block;
}

.simple_form .hint {
  clear: left;
  margin-left: 120px;
  font-size: 12px;
  color: #555;
  display: block;
  font-style: italic;
}

Затем перезагрузите страницу и ... Тадаа ... первый удар ... after adding a default simple_form stylesheet

12) А если вам не нравятся списки с множественным выбором, просто вернитесь к форме книг

приложение / просмотров / книги / _form.html.erb

и изменить строку

15      <%= f.input :author %>

немного до

15      <%= f.input :author, :as => :check_boxes %>

чтобы сделать флажки из списка ... но ... ээээ .... посмотрите на это: left to right checkbox display

13) что-то кажется немного неправильным ... известно, что представление опций слева направо время от времени создает проблемы с простыми формами, но на самом деле проблему легко исправить

и помимо этой небольшой проблемы с форматом, вы можете также увидеть возраст пользователей после его имени в фигурных скобках, например 'Tom (25)'

... так что давайте сделаем 3 быстрых исправления

a) раскомментируйте и установите 2 параметра в config / initializers / simple_form.rb, чтобы обернуть каждый флажок элементом div и поместить набор флажков в набор полей

  # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
  config.collection_wrapper_tag = :fieldset

  # You can wrap each item in a collection of radio/check boxes with a tag, defaulting to none.
  config.item_wrapper_tag = :div

b) немного измените нашу таблицу стилей simple_form.css, например, добавив:

fieldset { border: 0; }

... если вы не предпочитаете большую уродливую границу вокруг набора полей

c)создайте метод 'to_label' в нашей пользовательской модели, так как 'to_label' по умолчанию является первым методом, который ищет simple_form для получения String-представления для отображения объекта.По странному происшествию у нашей модели User есть колонка с именем 'name'.Поскольку name также является методом simple_form, который ищет в модели, нам повезло, что это приложение до сих пор работало.Если бы вместо этого мы назвали имя столбца именем, Rails перечислил бы не имена пользователей, а представления объектов ruby-объекта по умолчанию (например, <#User: 521369846>).Полагаю, нам повезло ;-)

app / models / user.rb

class User < ActiveRecord::Base
  has_and_belongs_to_many :users

  def to_label
    "#{name} (#{age})"
  end

end

и форма редактирования выглядит хорошо ... nice and cozy edit view

14) Теперь для отображения владельцев книг требуется только представление представления ... это тоже не сложно, просто откройте представление show

app / views / books / show.html.erb

и добавьте строки 13-16, чтобы отобразить владельцев книг:

01    <p id="notice"><%= notice %></p>
02    
03    <p>
04      <b>Title:</b>
05      <%= @book.title %>
06    </p>
07    
08    <p>
09      <b>Author:</b>
10      <%= @book.author %>
11    </p>
12    
13    <p>
14      <b>Who owns a copy?</b>
15      <%= @book.users.map {|x| x.to_label}.join ', ' %>
16    </p>
17    
18    <%= link_to 'Edit', edit_book_path(@book) %> |
19    <%= link_to 'Back', books_path %>

и, наконец, что не менее важно ... представление шоу Who owns a book?

15) Ну, так много для быстрогоучебник к habtm или на словах has_and_belongs_to_many ассоциации в рельсах.Я разместил свое тестовое приложение, которое я создал во время написания этого документа, по адресу https://1drv.ms/u/s!Alpu50oGtUZq7AiJkL08QqBiMAjb

0 голосов
/ 18 апреля 2011

Посмотрите учебник Райана Бэйта о полях токенов:

http://railscasts.com/episodes/258-token-fields

Это простой способ построить отношения "многие ко многим" в рельсах

...