как извлечь данные из базы данных, используя ассоциацию has_many - PullRequest
0 голосов
/ 01 июля 2019

у меня

таблица сообщений

и

message_pictures

таблица (она принадлежит таблице сообщений), и я хочу получить из каждого сообщения беспорядка (если оно есть) из

message_controller

.

Как я могу это сделать. Я занимался серфингом в Интернете, но нашел мало скудных объяснений.

Это класс сообщений (модель)

class Message < ApplicationRecord
  belongs_to :user
  has_many :message_pictures, dependent: :destroy
  accepts_nested_attributes_for :message_pictures
end

Это класс message_pictures (модель)

class MessagePicture < ApplicationRecord
  belongs_to :message, optional: true
  mount_uploader :message_pictures, PictureUploader
end

и это метод индекса класса message_controller

def index
    @user = User.find(current_user.id)#414, 449, 494
    @messages = @user.messages.paginate(page: params[:page])
    #@messages = @messages.message_pictures.paginate(page: params[:page])
end

Вы можете увидеть строку 4 метода index, чтобы увидеть, как я это сделал, но он не работает

1 Ответ

3 голосов
/ 01 июля 2019

Я верю, что вам нужно has_many ... :through

приложение / модели / user.rb

class User < ApplicationRecord
  # ...
  has_many :messages, dependent: :destroy
  has_many :message_pictures, through: :messages
end

приложение / контроллеры / messages_controller.rb

class MessagesController < ApplicationController
  # ...

  def index
    @user = User.find(current_user.id)
    @messages = @user.messages.paginate(page: params[:page])
    @message_pictures = @user.message_pictures
  end
end

has_many ... :through упрощает извлечение «вложенных» дочерних записей через «SQL JOINS», из которых обычно вы бы делали это более длинным (более явным образом), как показано ниже (что также работает):

class MessagesController < ApplicationController
  # ...

  def index
    @user = User.find(current_user.id)
    @messages = @user.messages.paginate(page: params[:page])
    @message_pictures = MessagePicture.joins(message: :user).where(
      messages: { # <-- this needs to be the table name, and not the association name, and is why it is in plural form
        users: { # <-- this needs to be the table name, and not the association name, and is why it is in plural form
          id: @user.id
        }
      }
    )
  end
end

Обновление: альтернативное решение

Оглядываясь назад на ваш вопрос, я чувствую, что вам нужно только @message_pictures, что соответствует @messages, а не всем @user.messages, потому что я заметил, что у вас есть разбиение на страницы для сообщений. Я сделаю это так вместо этого:

приложение / контроллеры / messages_controller.rb

class MessagesController < ApplicationController
  # ...

  def index
    @user = User.find(current_user.id)

    # the `includes` here prevents N+1 SQL queries, because we are gonna loop
    # through each `message_picture` in each `message` record (see index.html.erb below)
    @messages = @user.messages.includes(:message_pictures).paginate(page: params[:page])
  end
end

app / views / messages / index.html.erb (пример)

<h1>Messages:</h1>
<% @messages.each do |message| %>
  <section>
    <h2>Message:</h2>
    <p><%= message.content %></p>

    <h3>Message Pictures:<h3>
    <div>
      <% message.message_pictures.each do |message_picture| %>
        <% message_picture.message_pictures.each do |message_picture_attachment| %>
          <%= image_tag message_picture_attachment.url.to_s %>
        <% end %>
        <br>
      <% end %>
    </div>
  </section>    
<% end %>

^ Выше предполагается, что MessagePicture использует carrierwave. Постскриптум Мне кажется, что что-то не так с тем, как вы определили свои модели, потому что у вашего message есть много message_pictures, в то время как у каждого из message_picture также есть много прикрепленных message_picture вложений в транспортную волну (при условии, что вы использовали «несколько файлов» "загрузка настроена для carrierwave, потому что вы использовали mount_uploader :message_pictures, PictureUploader вместо mount_uploader :message_picture, PictureUploader. Проблема модели, я думаю, заключается в том, что она выглядит следующим образом: message <<code>message_pictures <<code>message_pictures attachments, но (в зависимости от вашего варианта использования) , это, вероятно, должно быть просто message <<code>message_pictures - message_picture attachment или просто message <<code>message_pictures attachments

...