Ismoh
Ismoh

Reputation: 1104

How can I get access to foreign_key?

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!


EDIT:
I gather all the data in the 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_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:
enter image description herehttps://i.sstatic.net/Apg7y.png

  1. users
  2. schedules_users (join-table with fk)
  3. schedules

Upvotes: 1

Views: 95

Answers (2)

Richard Peck
Richard Peck

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

--

has_and_belongs_to_many

Simply, you can't access the has_and_belongs_to_many table directly, as it has no primary_keys in place.

enter image description here

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

deyan
deyan

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.

  1. Based on your view, to get all users for a schedule, all you would need is to replace schedules.users_belongs_to withschedule.users.

  2. 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.

  3. 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

Related Questions