Reputation: 1936
I want to print the values taken from two different tables in the database in a table on the view page. I am not getting how to handle two each iterators as it is behaving abnormally i.e Printing a value several times. I am very much confused. Please help.
Here is my code
In the controller:
class ListController < ApplicationController
def all
@books = Book.all
@susers = SUser.all
end
end
In my view page
<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>
The output is displayed like this
The else
part of the first if
statement is repeating it self again and again. I dont know why it is happening?
There are 3 models in this project. 1. User - Made by devise 2. Book 3. SUser
One important thing: - Actually i made SUser model because i want to store user's personal details such as name, address, phone no. I dont want to touch devise model (User) so i made another model SUser which has one to one relation with devise model(User).
User model:
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
Book Model:
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
SUser model:
class SUser < ActiveRecord::Base
# attr_accessible :title, :body
has_one :user
has_many :books
attr_accessible :user_id, :fullname, :email, :address, :details
end
Migrations files:
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 migration file
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
I made many to many relationship between user and book since one user have many books and one book can be available to many users. So i made a simple join table for many to many association
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
Lol.. I have pasted my whole code over here. Actually i am new to rails.. Please guide me if you find any other flaw to this code. Thanks
Upvotes: 0
Views: 127
Reputation: 5390
You can define relations between your models, I think one to many
relation type is suitable for your situation:
class Book < ActiveRecord::Base
belongs_to :suser, :class_name => "SUser"
end
class SUser < ActiveRecord::Base
has_many :books
end
Then in your controller you can write like this:
class ListController < ApplicationController
def all
@books = Book.includes(:suser).all
end
end
And finally your view will look like:
<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>
P.S.: it's normal that you have repeating of else
block because you check for each user if book.suser_id == suser_id
(but there is a one to many relation between books and susers, so book belongs to only one user, to few in case you have many to many relation)
Upvotes: 1
Reputation: 1478
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>
Finally you will need a foreign key for the relationship, something like:
script/generate migration add_user_id_to_books
migration syntax can be tricky so open up the migration file (in db/migrate) and make sure that it is doing something similar to add_column :books, user_id, integer
Upvotes: 1