Reputation: 1104
There are
The models has_and_belongs_to_many each other.
I can add a relationship with @user.schedules << @schedule
in the controller.
How can I get access to the join-table 'users_schedules' ?
I want to show the users which has_and_belongs_to_many schedules:
I thought about something like this: schedules.users_belongs_to
. As you can see in the view-code below.
view: (There is an example I want to add)
<table class="table table-hover">
<tbody>
<% @user_schedules_date.sort.each do |date_time, schedules| %>
<tr class="thead success">
<th colspan="4" scope="col"><p><%= date_time.strftime("%A, %d.%m.%Y") %></p></th>
</tr>
<% for schedule in schedules %>
<tr>
<th scope="row"><p><%= schedule.titel %></p></th>
<td><p><%= schedules.users_belongs_to #ALL USERS WHO ARE BINDED TO THIS SCHEDULE# %></p></td>
<td><p><%= schedule.date_time.strftime("%H:%M:%S") %></p></td>
<td><p><%= schedule.location %></p></td>
<td>
<p>
<%= link_to 'Bearbeiten', {:controller => 'schedule', :action => 'edit', :id => schedule.id} %>
oder
<%= link_to 'löschen', {:controller => 'schedule', :action => 'delete', :id => schedule.id} %>
</p>
</td>
</tr>
<% end %>
<% end %>
</tbody>
</table>
In the controller I tried the following, but I don't know how to replace/fit the placeholder (:email)
.
controller:
class WelcomeController < ApplicationController
def index
if(current_user)
@user_schedules = current_user.schedules
@user_schedules_date = @user_schedules.order(:date_time).group_by { |sched| sched.date_time.beginning_of_day }
@users_schedules_shared = User.find_by(:email) #HERE I NEED THE USER WHICH BELONGS_TO THIS SCHEDULE
end
end
end
I hope you can understand my problem.
Thanks for your help!
class WelcomeController < ApplicationController
def index
if(current_user)
@user_schedules = current_user.schedules
@user_schedules_date = @user_schedules.order(:date_time).group_by { |sched| sched.date_time.beginning_of_day }
@users_all = User.includes(user_schedules: :schedules)
end
end
end
and edit the view as the following:
<% @users_all.each do |user| %>
<% user.name %>
<% end %>
But I get the following error:
Association named 'user_schedules' was not found on User; perhaps you misspelled it?
I red this, as deyan said, but I dont understand it.
@users_all = User.includes(user_schedules: :schedules)
<- returns an array ?!?? (If I understood it correctly)
So I need each array-item.name to show the Users name??
Can anyone tell me what I am doing wrong?
Database:
https://i.sstatic.net/Apg7y.png
Upvotes: 1
Views: 95
Reputation: 76784
I want to show the users which
has_and_belongs_to_many
schedules
This will use something called a many-to-many
relationship - meaning that if you access the associated data through a model - you'll have an appended attribute / method to capture them.
So what you'd do is the following:
#app/models/schedule.rb
Class Schedule < ActiveRecord::Base
has_and_belongs_to_many :users
end
#app/models/user.rb
Class User < ActiveRecord::Base
has_and_belongs_to_many :schedules
end
This will append a collection
to each of these model objects, allowing you to call the collection as required:
@schedules = Schedule.all
@schedules.each do |schedule|
schedule.users #-> outputs a collection
schedule.users.each do |user|
user.name
end
end
Using includes
with Rails is actually quite a bad thing, considering you can call ActiveRecord associations to do the heavy-lifting for you
--
Simply, you can't access the has_and_belongs_to_many
table directly, as it has no primary_keys
in place.
Rails basically uses the relational database
infrastructure (through ActiveRecord
) to access the associative data. This means that if you're using this particular type of table, you'll just be able to access the collection
it provisions:
#app/models/user.rb
Class User < ActiveRecord::Base
has_and_belongs_to_many :schedules
end
#app/models/schedule.rb
Class Schedule < ActiveRecord::Base
has_and_belongs_to_many :users
end
This will allow you to access:
@user = User.find 1
@user.schedules #-> shows schedules collection. You will have to loop through this
Upvotes: 1
Reputation: 112
If I understand you correctly, you want to show the schedules for your current user, and for each schedule to show what other users belong to it.
Based on your view, to get all users for a schedule, all you would need is to replace schedules.users_belongs_to
withschedule.users
.
If you want to get together all unique users for all the schedules the current user might have, then in the controller you could do current_user.schedules.collect{|s| s.users|}.uniq
. This is only useful if you want to show all users, no matter which schedule each user belongs to.
I would advice you to gather all the data in the controller and then to print it in the view. You could join all tables in a single call to the DB, which might look something like this: User.includes(users_schedules: :schedules)
but you would need to adapt it depending on what your models are called.
Methods 1 or 2 are solving your problem using your current code, but might be slow. I would suggest you read more here: http://guides.rubyonrails.org/active_record_querying.html and get all data at once (method 3).
Upvotes: 0