Рельсы 3 леса реляционной модели

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

Ответы

Ответ 1

Этот тэг я написал при создании ниже тестового теста шаг за шагом, используя 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), тогда вам нужно создать таблицу соединений для этой asssociation... по умолчанию 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 therfore, я не добавил ничего, связанного с установкой системы управления базами данных, но как есть много, и на самом деле все, что достаточно достойно для использования, очень хорошо документированы, вы найдете любую помощь в этом довольно быстро)

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;
}

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

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

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

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

15      <%= f.input :author %>

слегка до

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

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

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

и помимо этой небольшой проблемы с форматом, вы также можете увидеть возраст пользователей позади своего имени в фигурных скобках, например "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, как в add:

fieldset { border: 0; }

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

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

приложение/модели/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.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

Ответ 2

Смотрите учебник Ryan Bate по полям токенов:

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

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