0

我想在视图页面的一个表中打印取自数据库中两个不同表的值。我不知道如何处理两个每个迭代器,因为它的行为异常,即多次打印一个值。我很困惑。请帮忙。

这是我的代码

在控制器中:

class ListController < ApplicationController

  def all
    @books = Book.all   
    @susers = SUser.all    
  end
end

在我的视图页面中

<tbody>                     
  <% @books.each do |b| %>
    <% if b.branch == "I.T" %>                                      
      <tr>
        <td><%= b.id %></td>
        <td><%= b.book_name %></td>
        <td><%= b.year %></td>
        <td><%= b.user_id %></td>    

        <% @susers.each do |s| %>                   
          <% if s.user_id == b.user_id %>
            <td><%= s.address %></td>
          <% else %>
            <td>Error..!!</td>
          <% end %>
        <% end %>                       
      </tr> 
    <% else %>
      <% puts "No any book of this branch" %>   
    <% end %>                                       
  <% end %>                                 
</tbody>

输出显示如下

第一条语句的else部分if是一次又一次地重复它自己。我不知道为什么会这样?您可以看到错误部分打印了四次,因为 book 表在数据库中有 4 本书。

这个项目有3个模型。1. 用户 - 由设计制作 2. 书籍 3. SUser

一件重要的事情: - 实际上我制作了 SUser 模型,因为我想存储用户的个人详细信息,例如姓名、地址、电话号码。我不想触摸设计模型(用户),所以我制作了另一个模型 SUser,它与设计模型(用户)具有一对一的关系。

用户型号:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :token_authenticatable, :confirmable,
  # :lockable, :timeoutable and :omniauthable
  has_and_belongs_to_many :books
  has_one :s_user
  devise :database_authenticatable, :registerable,
       :recoverable, :rememberable, :trackable, :validatable

  # Setup accessible (or protected) attributes for your model
  attr_accessible :email, :password, :password_confirmation, :remember_me
  # attr_accessible :title, :body

end

图书型号:

class Book < ActiveRecord::Base
  # attr_accessible :title, :body
  has_and_belongs_to_many :users
  belongs_to :s_user, :class_name => "SUser"
  attr_accessible :id, :user_id, :book_name, :edition, :author, :branch, :publisher,      :year, :details 
end

S用户型号:

class SUser < ActiveRecord::Base
  # attr_accessible :title, :body
  has_one :user
  has_many :books
  attr_accessible :user_id, :fullname, :email, :address, :details 
end

迁移文件:

class CreateBooks < ActiveRecord::Migration
  def change
    create_table :books do |t|
    t.integer "user_id", :limit =>5
    t.string "book_name", :limit => 50
    t.integer "edition", :limit => 5
    t.string "author", :limit => 30
    t.string "branch", :limit => 30
    t.string "publisher", :limit => 50
    t.integer "year", :limit => 10     
    t.text "details"
    t.timestamps
  end
  add_index :books, "user_id"
 end
end

SUser 迁移文件

class CreateSUsers < ActiveRecord::Migration
 def change
  create_table :s_users do |t|
    t.integer "user_id", :limit => 5
    t.string "fullname", :limit => 25            
    t.string "email", :default => "", :null => false
    t.string "hashed_password", :limit => 40
    t.string "salt", :limit => 40
    t.string "address",:limit => 25
    t.text "details"
    t.timestamps
  end
  add_index :s_users, "user_id"
 end
end

我在用户和书之间建立了多对多的关系,因为一个用户有很多书,而一本书可以供许多用户使用。所以我为多对多关联制作了一个简单的连接表

class CreateBooksUsersJoin < ActiveRecord::Migration
 def up
   create_table :books_users, :id => false do |t|
     t.integer "book_id"
     t.integer "user_id"
   end
  add_index :books_users, ["book_id", "user_id"]
 end

 def down
  drop_table :book_users
 end
end

大声笑..我已将整个代码粘贴在这里。实际上我是 Rails 新手。如果您发现此代码有任何其他缺陷,请指导我。谢谢

4

2 回答 2

1

您可以定义模型之间的关系,我认为one to many关系类型适合您的情况:

class Book < ActiveRecord::Base
  belongs_to :suser, :class_name => "SUser"
end

class SUser < ActiveRecord::Base
  has_many :books
end

然后在你的控制器中你可以这样写:

class ListController < ApplicationController
  def all
   @books = Book.includes(:suser).all
  end
end

最后,您的视图将如下所示:

<tbody>                     
<% @books.each do |b| %>
  <% if b.branch == "I.T"%>                                       
  <tr>
    <td><%= b.id%></td>
    <td><%= b.book_name%></td>
    <td><%= b.year%></td>
    <td><%= b.user_id%></td>    
    <td><%= b.suser.try(:address) %></td>
  </tr>   
  <%else%>
    <% puts "No any book of this branch"%>  
  <%end%>                                     
<%end%>                                 
</tbody>

PS:你有重复else块是正常的,因为你检查每个用户是否book.suser_id == suser_id(但书籍和用户之间存在一对多关系,所以书籍只属于一个用户,如果你有多对多关系,则很少)

于 2012-10-25T20:56:38.923 回答
1
class Book < ActiveRecord::Base
  belongs_to :suser
end

class SUser
  has_many :books
end

class ListController < ApplicationController
  def all
    @books = Book.includes(:susers).all
  end
end

<tbody>                     
<% @books.each do |b| %>
  <% if b.branch == "I.T"%>                                       
  <tr>
    <td><%= b.id%></td>
    <td><%= b.book_name%></td>
    <td><%= b.year%></td>
    <td><%= b.user_id%></td>    
    <td><%= b.suser.address %></td>
  </tr>   
  <%else%>
    <% puts "Branch has no books"%>  
  <%end%>                                     
<%end%>                                 
</tbody>

最后,您将需要关系的外键,例如:

script/generate migration add_user_id_to_books

迁移语法可能很棘手,因此打开迁移文件(在 db/migrate 中)并确保它正在执行类似于 add_column 的操作:books, user_id, integer

于 2012-10-25T20:59:28.883 回答