I have two tables - positions table with the fields id, position_id, first_name and last_name. The other table is positionslist with the fields id, positions.How will i able to join that two tables?
Here's my positionscontroller:
class PositionsController < ApplicationController
def index
##positions = Position.all(:order=>'updated_at DESC')
#positions = Position.joins(:positions => :positionlists)
end
def new
#position = Position.new
end
def create
#position = Position.new(params.require(:position).permit(:position_id, :first_name, :last_name))
if #position.save
redirect_to(:controller=>'positions')
else
render 'new'
end
end
def edit
#position = Position.find(params[:id])
end
def update
#position = Position.find(params[:id])
if #position.update(params.require(:position).permit(:position_id, :first_name, :last_name))
redirect_to(:controller=>'positions')
else
render 'edit'
end
end
def destroy
#position = Position.find(params[:id])
#position.destroy
redirect_to(:controller=>'positions')
end
end
my models position.rb
class Position < ActiveRecord::Base
has_many :positionlists
has_many :positionlists , :through => :positions
validates :first_name, length: { in: 4..20}
validates :last_name, length: { in: 4..20}
end
my models positionlists.rb
class Positionlists < ActiveRecord::Base
has_many :positions
end
any my postions index.html.erb
<% content_for :title, "Positions" %>
<%= render "layouts/nav" %>
<div class="clear"></div>
<h1>Positions List</h1>
<%= link_to "Add", new_position_path, :class =>'btn btn-success' %>
<br />
<br />
<table class="table">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Position</th>
<th>Options</th>
</tr>
<% #positions.each do |positions| %>
<tr>
<td><%= positions.first_name %></td>
<td><%= positions.last_name %></td>
<td><%= positions.position_id %></td>
<td>
<%= link_to "Edit", edit_position_path(positions)%> |
<%= link_to "Delete", position_path(positions),
method: :delete, data:{confirm: 'Are you sure you want to delete this?.' }%>
</td>
</tr>
<% end %>
</table>
any help is greatly appreciated! thanks
Rails takes care of this for you.
class PositionList < ActiveRecord::Base
has_many :positions
end
class Position < ActiveRecrod::Base
belongs_to :position_list
end
Also your position needs a position_list_id column for simplicity. If I'm understanding what you are trying to do here.
Other problems: naming your class PositionLists and not PositionList will confuse Rails automagic naming conventions.
Also you have an odd set of columns in your tables. For what you want as far as I can tell your positions table needs to have the columns:
first_name
last_name
id (automatic)
You don't appear to have anything in your position_list table so there's no column you need there outside of the automatic id column. The association is automatic from the belongs_to in the Position class and the position_list_id column in the positions table.
If you want to get an idea of how simple this all can be try running an automatic scaffolding, looking at how it's done there, and learning from that. Maybe a generate a fresh Rails app and then run something like this:
rails g scaffold position_list name
rails g scaffold position first_name last_name position_list:references
This will give you position_list.positions to get all positions for any position_list or Position.all for a list of all positions.
Also it sounds like a lot of Rails is new to you. Hartl's classic is a great intro: http://ruby.railstutorial.org/ruby-on-rails-tutorial-book
Related
Model
class Register < ActiveRecord::Base
attr_accessor :code
belongs_to :user
end
class User < ActiveRecord::Base
has_many :register
end
Controller
def index
#registers = Register.all
end
View
<p> All Registers </p>
<table>
<tr>
<td> User </td>
<td> Point </td>
</tr>
<% #registers.each do |u| %>
<tr>
<td> <%= u.user.name %> </td>
<td> <%= u.hour %> </td>
</tr>
<% end %>
</table>
it onlys display Name instead of the field value
and the console is giving me this error
no such column: users.register_id: SELECT "users".* FROM "users" WHERE "users"."register_id" = ? LIMIT 1
First Add user_id to registers table.
Update your index action to below.
def index
#registers = Register.all
end
and view code to following.
<% #registers.each do |u| %>
<%= u.user.name %>
<%= u.hour %>
<% end %>
Update you user model to below.
class User < ActiveRecord::Base
has_many :registers
end
To add to #Dheeresha's great answer, you need to also appreciate that you actually have to associate the two objects. To do this, you can use the following (as a test):
$ rails c
$ user = User.first
$ register = Register.first
$ user.registers << register
This will ensure you have at least one register in the user.registers collection. The way to ensure this is not an issue in production / view is to use the .try method:
<% #registers.each do |u| %>
<%= u.user.try(:name) %>
<%= u.hour %>
<% end %>
The only reason you wouldn't be able to access the user object would be that it's not associated in ActiveRecord. This issue in itself could be caused by not having the associations defined correctly (as #Dheeresha pointed out), or not associating the objects (as I've mentioned).
--
Your models should look like:
#app/models/user.rb
class User < ActiveRecord::Base
has_many :registers
end
#app/models/register.rb
class Register < ActiveRecord::Base
belongs_to :user
end
I have included
class User < ActiveRecord::Base
has_and_belongs_to_many :subjects
end
class Subjects < ActiveRecord::Base
has_and_belongs_to_many :users
end
I have created one table i.e subjects_users having subject_id and user_id
<% Subject.all.each do |subject| %>
<tr>
<td><%= subject.name %></td>
<td><%= link_to 'Select Subject', final_subject_subject_path(subject) %></td>
</tr>
<% end %>
It goes in controller method:
def final_subject
# now please guide me what I have to write in this so that when select subject is clicked than it will both current_user.id and subject.id in associated table
end
Please help me out in solving this. Thanks in advance
To create subjects for a particular user, you can do it as:
def final_subject
#subject = Subject.find(params[:id)
current_user.subjects << #subject
end
Hello i created 2 tables (categories and employees),both are in a relationship and i want to show category_name(Categories table) in my employees index view instead of id's
****Here is my Categories Table******
class CreateCategories < ActiveRecord::Migration
def self.up
create_table :categories do |t|
t.string :category_name
end
end
def self.down
drop_table :categories
end
end
****Here is my Enployees Table******
class CreateEmployees < ActiveRecord::Migration
def self.up
create_table :employees do |t|
t.string :name
t.string :last_name
t.integer :categories_id
end
execute "ALTER TABLE employees ADD CONSTRAINT fk_employees_categories FOREIGN KEY (categories_id) REFERENCES categories (id)"
end
def self.down
drop_table :employees
end
end
****Here is my Employee controller******
class EmployeeController < ApplicationController
def index
#employees = Employee.all
end
end
****Here is my Category controller******
class CategoryController < ApplicationController
def index
#categories = Category.all
end
end
****Here is my Category Model******
class Category < ActiveRecord::Base
has_many :employees
end
****Here is my Employee Model******
class Employee < ActiveRecord::Base
belongs_to :category
end
****Here is Employee view*******
<table>
<tr>
<th>Employee</th>
<th>Last Name</th>
<th>Category</th>
</tr>
<% #employees.each do |e| %>
<tr>
<td><%=h e.name %></td>
<td><%=h e.last_name %></td>
<td><%=h e.categories_id %>
</td>
Here in e.categories_id i want to show categories_name that is from my categories table
<td>
<%= link_to ("View" ,:controller=>"employee",:action=>"show", :id=>e.id ) %>
</td>
<td>
<%= link_to ("Edit", :controller=>"employee",:action=>"edit",:id=>e.id ) %>
</td>
<td>
<%= link_to ( "Delete",:controller=>"employee",:action=>"destroy", :id=>e.id ,:confirm=>"sure?" %>
</td>
</tr>
<% end %>
</table>
Can someone help me with this problem please?
In your employee index views,
<td><%=employee.categories.category_name %>
instead of
<td><%=h e.categories_id %>
<%= h e.category.category_name %>
will do the trick.
Note that if you just do this, it will cause an SQL query to be executed for each row that you're displaying (known as the N+1 problem).
So in your controller, you'll have to change
#employees = Employee.all
to
#employees = Employee.find(:all, :include => [:category])
This will force eager loading, and reduce the number of queries to 2.
(As a side note, you really should have moved on to Rails 3 by now. Rails 4 is current. Each version offers a lot more features than the last.)
In Your employee controller add this
It means that get category_name to appear on your index view instead of ID.
#category= Category.all()
#category_list=[]
#category.each do |c|
#category_list << [c.category_name,c.id]
end
and then in your index views
<td><%=employee.categories.category_name %>
I know this is a late answer, but for anyone who is looking for an answer, here is how I accomplished this,
I have a table realties that has a one to many association with features table. I used the railscast method for multiple checkbox selection, so for each realty it has certain features. I wanted to show the features of each realty in its row in the index view. I had in the show view, features are shown like this,
#realty.feature_ids
where #realty in the controller is
#realty = Realty.find(params[:id])
however, in the index view the realty.feature_ids only showed numbers only not the names.
To work this out here is what I did in the index view:
<% #realties.each do |realty| %>
<td>
<% realty.feature_ids.each do |feature| %>
<%= Feature.find(feature).name %>
<% end %>
</td>
<% end %>
so for the above question, loop through the ids with each loop, this will give you the id number, find it in the Category model with the .name method. So I guess the solution for you would look like this:
<% #employees.each do |employee| %>
<td>
<% employee.category_ids.each do |category| %>
<%= Category.find(category).name %>
<% end %>
</td>
<% end %>
I hope this will benefit someone.
I am new to the Rails framework and tried very long to fix this problem...
I want to display the team name a certain user belongs to, which works for the show action (user details), but not for the index action (all users)
I've created tables:
teams users
----------- ---------------
id (integer) id(integer)
name (string) fname(string)
lname(string)
team_id(integer)
I have the following classes:
class Team < ActiveRecord::Base class User < ActiveRecord::Base
attr_accessible :name, :user_id attr_accessible :fname, :lname, :team_id
has_many :users belongs_to :team
Then I have the following User controller:
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
end
def index
#users = User.paginate(page: params[:page], per_page: 15)
end
..and the code to display the user's team name is
Team: <%= #user.team[:name] %>
... which works perfectly fine... however, when I try to use the same code in the index view, like this, I get an error "undefined method `team' for nil:NilClass".
<table class="table table-striped">
<% #users.each do |user| %>
<tr>
<td>
<%= "#{user.fname} #{user.lname}" %>
</td>
<td>
Team: <%= #user.team[:name] %>
</td>
</tr>
<% end %>
</table>
What did I do wrong? Thanks for your help, I'd really appreciate it!
You're inside a block.
Instead of doing
Team: <%= #user.team[:name]
You should write
Team <%= user.team[:name]
Easy bug to overlook :)
My goal is to display select box for each relation for users and specific project.
All users need to be listed but only project users have some type of relation. Other users have none selected in theirs select box.
I have this model:
class Project < ActiveRecord::Base
belongs_to :company
has_many :tasks, :order => 'state_type_id ASC'
has_many :project_user_relations
has_many :users, :through => :project_user_relations
def t_name
name.camelcase
end
end
class User < ActiveRecord::Base
belongs_to :company
has_many :tasks , :foreign_key => :assigned_user_id
has_many :project_user_relations
has_many :projects, :through => :project_user_relations
def full_name
firstname + ' ' + lastname
end
def relation_to(project)
relation=ProjectUserRelation.find_by_project_id_and_user_id(project.id, id)
relation ||= relation=ProjectUserRelation.new
end
end
class ProjectUserRelation < ActiveRecord::Base
belongs_to :project
belongs_to :user
has_one :project_user_relation_type
end
class ProjectUserRelationType < ActiveRecord::Base
def t_name
I18n.t("app.projects.users.relation.type."+code)
end
end
I want make a form to display all users, with collection_select.
I used code:
def edit_all
#project = Project.find(params[:project_id])
#users = User.all
....
in my controler
routes works ok.
in my view:
<% #users.each do |user| %>
<%= f.fields_for :users, user do |user_fields| %>
<tr class="reference" rel="<%= parent_user_path(user) %>" >
<td class="name"><%= link_to user.full_name, parent_user_path(user) %></td>
<td class="email"><%= mail_to user.email %></td>
<td class="type">
<%= user_fields.fields_for user.relation_to #project do |relation_fields| %>
<%= relation_fields.collection_select :project_user_relation_type, ProjectUserRelationType.all, :id, :t_name, {:include_blank => false, :prompt => t("helpers.select.prompt") } %>
<% end %>
</td>
</tr>
<% end %>
<% end %>
or for test:
<%= f.fields_for :users, #users do |xuser_fields| %>
<% logger.debug "#{self.to_s} xuser_fields = #{xuser_fields.object.inspect} ;" %>
<tr>
<td><%= xuser_fields.text_field :firstname %></td>
<td></td>
<td></td>
<td></td>
</tr>
<% end %>
but notnihng woks right
first one generates wrong name in html:
select id="project_users_project_user_relation_project_user_relation_type" name="project[users][project_user_relation][project_user_relation_type]"
second one generates error:
undefined method `firstname' for # Array:0x4d03658
Can you help me to solve this situation.
PS:sorry for long code :(
SOLUTION (probably - solved by reading RoR sources)
I found sollution i thing.
A method
def name_attributes=(attributes)
# Process the attributes hash
end
in Project model was missing.
It is unbelievable sollution :].
There is also exact syntax after fields_for: :name, #some_collection, where name must be exactly same name as in the beginign of mentioned def in Model.