首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >rails 3关系模型的搭建

rails 3关系模型的搭建
EN

Stack Overflow用户
提问于 2011-03-22 05:51:20
回答 2查看 11.7K关注 0票数 14

有没有关于如何搭建一个使用多对多关系的简单模型的教程?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-03-22 08:12:31

这篇教程是我在使用ruby 1.9.2 on Rails 3.0.5一步一步创建下面的测试应用时写的。有关我使用的gem,请参阅'Gemfile‘(整个Testapp可下载,链接在第15部分的末尾)。所以这里是这样的:

1)转到您想要创建测试应用的位置,然后

代码语言:javascript
运行
复制
rails new mynewtestapp
cd mynewtestapp

2)然后添加2个具有has_and_belongs_to_many关联的机型

代码语言:javascript
运行
复制
rails g scaffold book title:string author:string
rails g scaffold user name:string age:integer

3)然后,您需要为该关联创建连接表...默认情况下,rails将查找名称由两个相关表的名称组成的表,按字母顺序排列...因此,让我们创建一个迁移来创建这样一个表

代码语言:javascript
运行
复制
rails g migration createBooksUsers

4)打开生成的迁移文件,该文件如下所示

代码语言:javascript
运行
复制
class CreateBooksUsers < ActiveRecord::Migration
  def self.up
  end

  def self.down
  end
end

5)修改为如下所示

代码语言:javascript
运行
复制
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关联添加到图书和用户模型,以及由关系添加的新ids

app/model/book.rb

代码语言:javascript
运行
复制
class Book < ActiveRecord::Base
  attr_accessible :title, :author, :user_ids
  has_and_belongs_to_many :users
end

app/model/user.rb

代码语言:javascript
运行
复制
class User < ActiveRecord::Base
  attr_accessible: :name, :age, :book_ids
  has_and_belongs_to_many :books
end

7)现在我们的模型和迁移已经完成……让我们创建表

代码语言:javascript
运行
复制
rake db:create
rake db:migrate

(如果您使用sqlite3,或者如果您已经创建了要手动使用的数据库,那么可能不需要创建,这个示例将使用sqlite,因此我没有添加任何与安装数据库管理系统相关的内容。但由于有大量的,实际上所有值得使用的都被很好地记录下来了,你会很快找到任何关于这方面的帮助)

8)现在决定将哪个对象分配给哪个对象...当然你可以通过这两种方式来实现。我将保持简单,并向一个人演示这一点。假设您只有几个用户,并且希望将这些用户分配给图书……

在这一点上,我会说让我们获得一些外部帮助,就像二进制x建议的那样...但为了简单起见,我会选择simple_form gem而不是Formtastic。我想每个人都有自己的最爱..。但是simple_form似乎给了你更多的自由-样式的整个输出你的愿望…现在让我们安装simple_form,只需执行以下操作

代码语言:javascript
运行
复制
echo "gem 'simple_form', :git => 'git://github.com/plataformatec/simple_form.git'" >> Gemfile

将simple_form添加到Gemfile中,然后运行

代码语言:javascript
运行
复制
bundle install

并通过以下方式将简单表单安装到应用程序中(即生成配置、默认样式和语言文件

代码语言:javascript
运行
复制
rails g simple_form:install

9)是时候修改我们的账本表单了

现在的图书表单应该如下所示

app/views/book/_form.html.erb

代码语言:javascript
运行
复制
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行),因此整个文件将如下所示:

代码语言:javascript
运行
复制
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)现在,您可能想要启动应用程序

代码语言:javascript
运行
复制
rails s

添加一些用户,然后添加一本书,这就是您的第一个has_and_belongs_to_many表单:

11)嗯,这可能还不是最漂亮的东西,但简单地添加一个样式表就会有一点帮助……创建新文件

代码语言:javascript
运行
复制
public/stylesheets/simple_form.css

并将以下代码行粘贴到其中

代码语言:javascript
运行
复制
/* 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;
}

然后重新加载页面,然后...泰达..。第一次出击...

12)如果你不喜欢多项选择列表框,那就回到书的形式

app/views/book/_form.html.erb

和修改行

代码语言:javascript
运行
复制
15      <%= f.input :author %>

略微到

代码语言:javascript
运行
复制
15      <%= f.input :author, :as => :check_boxes %>

若要在列表框之外创建复选框,请...但是..。呃……看看这个:

13)有些地方似乎有点不对劲……众所周知,选项从左到右的呈现方式有时会给simple_form新手带来麻烦,但实际上这是一个很容易解决的问题

除了格式上的小问题,你可能还想看看用户在他名字后面的年龄,比如“Tom(25)”。

..。因此,让我们来做3个快速修复

a)取消注释并在config/initializers/simple_form.rb中设置2个选项,以便用div包装每个复选框,并将这组复选框放入一个字段集中

代码语言:javascript
运行
复制
  # 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:

代码语言:javascript
运行
复制
fieldset { border: 0; }

..。除非您希望字段集周围有一个又大又丑的边框

c)在我们的用户模型中创建方法'to_label‘,因为默认情况下'to_label’是simple_form为了获得字符串表示来显示对象而查找的第一个方法。由于一个奇怪的事件,我们的模型用户有一个名为'name‘的列。因为名字也是simple_form在模型中寻找的一个方法,我们很幸运这个应用程序到目前为止还可以工作。如果我们将name列称为forename,Rails将不会列出用户名,而会列出默认的ruby对象表示(例如<#User:521369846>)。我想我们很幸运;-)

app/model/user.rb

代码语言:javascript
运行
复制
class User < ActiveRecord::Base
  has_and_belongs_to_many :users

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

end

编辑表单会有一个很好的外观。

14)现在只有show视图需要显示图书所有者...这也不是很难,只要打开展览馆就行了。

app/views/book/show.html.erb

并添加13-16行以显示书主:

代码语言:javascript
运行
复制
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 %>

最后但同样重要的是..。显示视图

15)好了,关于habtm或者rails中的has_and_belongs_to_many关联的快速教程就到此为止了。我已经把我在写这篇文章时创建的测试应用程序放到了https://1drv.ms/u/s!Alpu50oGtUZq7AiJkL08QqBiMAjb

票数 45
EN

Stack Overflow用户

发布于 2011-04-18 12:45:25

观看Ryan Bate关于Token Fields的教程:

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

这是在rails中构建多对多关系的一种简单方法

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5384203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档