简体   繁体   中英

How to join on nested belongs_to in Ruby on Rails

I have three models, Application , which belongs to a Board , which belongs to a User .

class User < ActiveRecord::Base
  has_many :boards
end

class Board < ActiveRecord::Base
  belongs_to :user
  has_many :applications
end

class Application < ActiveRecord::Base
  belongs_to :board
end

I'm always only ever going to want to show the boards or applications for the current user. How can I say "show every application for the current board for the current user"? Basically how to query for something for specific parent id values.

You should provide the current user id and board id at first.

user = User.find(user_id)           #get current user
board = user.boards.find(board_id)  #get current board
board.applications                  #get every application

You can get more info from Rails Guide--Active Record Associations

show every application for the current board for current_user

The power of ActiveRecord should make this relatively simple:

board = current_user.boards.find params[:board_id]
board.applications #-> collection of Application objects for board

This assumes you're using devise , and thus have access to the current_user method.

If not, you'll be able to use something like the following:

#config/routes.rb
resources :users do
    resources :applications #-> url.com/users/:user_id/applications
end

#app/controllers/applications_controller.rb
class ApplicationsController < ApplicationController
   def index
      @user = User.find params[:user_id]
      @boards = @user.boards
   end
end

#app/views/applications/index.html.erb
<% @user.boards.each do |board| %>
   <%= board.name %>
      <% board.applications.each do |application| %>
         <%= application.name %>
      <% end %>
   <% end %>
<% end %>

ORM

I'll give you some context to this (hopefully it will help you in the future).

Firstly, you must understand that Rails is built on top of a relational database - or at least it should be. Relational databases use foreign_keys to give you access to associative data objects:

在此处输入图片说明

Whilst this might not seem important, it explains the entire functionality of the ActiveRecord system.

ActiveRecord is what's known as an ORM (Object Relationship Mapper)... in short, gives you the ability to populate objects with associative data from your relational database.

In the case of Ruby/Rails, the object orientated nature of ActiveRecord is a direct result of Ruby. That is, Ruby is an object orientated language; everything you do in it revolves around objects:

在此处输入图片说明

With Rails, those objects are built in the models .

Thus, if you want to understand how Rails works - you really need to get down to the model level -- you have to understand that calling Model.find x will build an object around that model, populating it with data from your database.

It's very clever.

The associations are provided by ActiveRecord, and pulled through the relational database infrastructure. This means that you can call the likes of @board = @user.boards.first and populate with the correct data.

Here's a good demonstration of how it works:

在此处输入图片说明

I'd share about how running query with ActiveRecord::Relation . To know about query, no matter you want to show data that far away from the current table but when those have associations, those could be connected.

Step by step to do query:

  1. Determine all relations tables

Here, you have to determine tables that related to its table associations. In this case: users, boards, and applications.

  1. Determine the condition

You can put current_user is a condition. You need users, boards, applications

So the condition is:

User.joins(boards: :applications).where("users.id = ?", current_user.id)

NOTE:

I would try to explain. User joins boards because user has many boards. Next boards has many applications so we have to join boards with application into boards: :applications .

This is good explain for query has many through associations. activerecord-query-through-multiple-joins

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM