rails 3关系模型的脚手架

lur*_*her 14 mysql entity-relationship ruby-on-rails ruby-on-rails-3

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

Ing*_*ngo 45

这是我在Rails 3.0.5上使用ruby 1.9.2逐步创建下面的testapp时编写的.另请参阅我使用的宝石的'Gemfile'(整个Testapp可下载,链接在第15部分的末尾).所以这里:

1)然后转到你想要创建测试应用程序的地方

rails new mynewtestapp
cd mynewtestapp
Run Code Online (Sandbox Code Playgroud)

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

rails g scaffold book title:string author:string
rails g scaffold user name:string age:integer
Run Code Online (Sandbox Code Playgroud)

3)然后你需要为该asssociation创建连接表...默认情况下,rails将查找一个表,其名称由字母顺序的两个关联表组成...所以让我们创建一个迁移来创建这样的表

rails g migration createBooksUsers
Run Code Online (Sandbox Code Playgroud)

4)打开生成的迁移文件,此时就是这样

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

  def self.down
  end
end
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

6)将has_and_belongs_to_many关联添加到书籍和用户模型,以及关系添加的新ID

应用程序/模型/ book.rb

class Book < ActiveRecord::Base
  attr_accessible :title, :author, :user_ids
  has_and_belongs_to_many :users
end
Run Code Online (Sandbox Code Playgroud)

应用程序/模型/ user.rb

class User < ActiveRecord::Base
  attr_accessible: :name, :age, :book_ids
  has_and_belongs_to_many :books
end
Run Code Online (Sandbox Code Playgroud)

7)现在我们的模型和迁移完成了......让我们创建表格

rake db:create
rake db:migrate
Run Code Online (Sandbox Code Playgroud)

(如果你使用sqlite3或者如果你已经创建了手动使用的数据库,那么可能没有必要创建这个例子,因为我没有添加任何与安装数据库管理系统相关的东西.但是因为有很多实际上所有值得使用的都有很好的记录,你会发现任何有关这方面的帮助很快)

8)现在决定将哪个对象分配给哪个对象......当然,你可以做到这两种方式......我会保持简单,并向一个人展示......让我们说你只有少数用户和想把这些分配给书籍......

在这一点上,我会说让我们得到一些外部帮助,比如二进制x建议......但为了简单起见,我选择了Simple_form宝石而不是Formtastic.我想每个人都有自己的最爱......但是simple_form似乎可以让你更自由地根据自己的意愿设计整个输出...所以让我们在这一点上安装simple_form,就这么做

echo "gem 'simple_form', :git => 'git://github.com/plataformatec/simple_form.git'" >> Gemfile
Run Code Online (Sandbox Code Playgroud)

将simple_form添加到Gemfile,然后运行

bundle install
Run Code Online (Sandbox Code Playgroud)

并将简单的表单安装到您的应用程序(即生成配置,默认样式和语言文件)

rails g simple_form:install
Run Code Online (Sandbox Code Playgroud)

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 %>
Run Code Online (Sandbox Code Playgroud)

使用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 %>
Run Code Online (Sandbox Code Playgroud)

10)现在您可能想要启动您的应用程序

rails s
Run Code Online (Sandbox Code Playgroud)

添加一些用户,然后添加一本书,并且有第一个has_and_belongs_to_many表单: 第一个simple_form表单没有特殊效果

11)那可能还不是最美的东西,但是简单地添加样式表会有所帮助...创建一个新文件

public/stylesheets/simple_form.css
Run Code Online (Sandbox Code Playgroud)

并将以下行粘贴到其中

/* 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;
}
Run Code Online (Sandbox Code Playgroud)

然后重新加载页面...... Tadaa ......先攻...... 添加默认的simple_form样式表后

12)如果您不喜欢多选列表框,请返回图书表格

应用程序/视图/书籍/ _form.html.erb

并修改行

15      <%= f.input :author %>
Run Code Online (Sandbox Code Playgroud)

稍微

15      <%= f.input :author, :as => :check_boxes %>
Run Code Online (Sandbox Code Playgroud)

从列表框中制作复选框......但是...... ewww ....看看这个: 从左到右复选框显示

13)有些东西似乎有点不对...已知这些选项的从左到右的表示会偶尔给simple_form greenhorns带来麻烦,但实际上这是一个容易解决的问题

除了那个小格式问题之外,您可能还希望在大括号中看到他的名字背后的用户年龄,例如'Tom(25)'

...所以我们做3个快速修复

a)取消注释并在config/initializers/simple_form.rb中设置2个选项,以便用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
Run Code Online (Sandbox Code Playgroud)

b)稍微修改一下simple_form.css样式表,如添加:

fieldset { border: 0; }
Run Code Online (Sandbox Code Playgroud)

...除非你更喜欢围绕场地设置的大丑陋边框

c)在我们的用户模型中创建方法'to_label',因为'to_label'默认是simple_form查找的第一个方法,以便获得一个String表示来显示一个对象.通过一个奇怪的事件,我们的模型用户有一个名为"名称"的列.正如名称也是一个方法simple_form在模型中寻找,我们很幸运这个应用程序到目前为止工作.如果我们调用名称列forename,Rails将列出不是用户名而是default-ruby-object表示(例如<#User:521369846>).猜猜我们很幸运;-)

应用程序/模型/ user.rb

class User < ActiveRecord::Base
  has_and_belongs_to_many :users

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

end
Run Code Online (Sandbox Code Playgroud)

编辑表格看起来很漂亮...... 漂亮舒适的编辑视图

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 %>
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的......展示视图 谁拥有一本书?

15)嗯,非常需要快速的教程来habtm或者在rails中使用has_and_belongs_to_many关联.我在网上写这个我创建的测试应用程序, 网址是https://1drv.ms/u/s!Alpu50oGtUZq7AiJkL08QqBiMAjb

  • 如果出现这种情况,出于安全原因,Rails 3.2.3会将属性列入白名单.这意味着您无法进行全面的update_attributes.您只需要添加"attr_accessible:x,:y",其中:x和:y是您要从视图更新到要更新的模型的任何字段. (2认同)