如何使用 has_many 关联从数据库中检索数据
how to retrieve data from the database using the has_many association
我有
message table
和
message_pictures
table(它属于消息 table),我想做的是从
中检索每个消息图片(如果有的话)
message_controller
。
我该怎么做。我在网上冲浪,但对它的解释很少。
这是消息class(型号)
class Message < ApplicationRecord
belongs_to :user
has_many :message_pictures, dependent: :destroy
accepts_nested_attributes_for :message_pictures
end
这是message_picturesclass(型号)
class MessagePicture < ApplicationRecord
belongs_to :message, optional: true
mount_uploader :message_pictures, PictureUploader
end
这是message_controllerclass
的索引方法
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行,看看我是怎么做的,但它不起作用
我相信你需要的是has_many ... :through
app/models/user.rb
class User < ApplicationRecord
# ...
has_many :messages, dependent: :destroy
has_many :message_pictures, through: :messages
end
app/controllers/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" 简化了对 "nested" 子记录的检索,通常你会用更长的(更明确的方式)完成它,如下所示(这也是作品):
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
,因为我注意到你有分页消息。我会这样做:
app/controllers/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
。 P.S。在我看来,您定义模型的方式有问题,因为您的 message
有许多 message_pictures
,而每个 message_picture
也有许多附加的 message_picture
载波附件(假设你使用 "multiple-file" 上传设置为载波因为你使用 mount_uploader :message_pictures, PictureUploader
而不是 mount_uploader :message_picture, PictureUploader
。我认为模型问题是因为它是这样的: message
< message_pictures
< message_pictures attachments
,但是(取决于你的 use-case),它可能应该就像 message
< message_pictures
- message_picture attachment
,或者只是 message
< message_pictures attachments
我有
message table
和
message_pictures
table(它属于消息 table),我想做的是从
中检索每个消息图片(如果有的话)message_controller
。
我该怎么做。我在网上冲浪,但对它的解释很少。
这是消息class(型号)
class Message < ApplicationRecord
belongs_to :user
has_many :message_pictures, dependent: :destroy
accepts_nested_attributes_for :message_pictures
end
这是message_picturesclass(型号)
class MessagePicture < ApplicationRecord
belongs_to :message, optional: true
mount_uploader :message_pictures, PictureUploader
end
这是message_controllerclass
的索引方法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行,看看我是怎么做的,但它不起作用
我相信你需要的是has_many ... :through
app/models/user.rb
class User < ApplicationRecord
# ...
has_many :messages, dependent: :destroy
has_many :message_pictures, through: :messages
end
app/controllers/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" 简化了对 "nested" 子记录的检索,通常你会用更长的(更明确的方式)完成它,如下所示(这也是作品):
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
,因为我注意到你有分页消息。我会这样做:
app/controllers/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
。 P.S。在我看来,您定义模型的方式有问题,因为您的 message
有许多 message_pictures
,而每个 message_picture
也有许多附加的 message_picture
载波附件(假设你使用 "multiple-file" 上传设置为载波因为你使用 mount_uploader :message_pictures, PictureUploader
而不是 mount_uploader :message_picture, PictureUploader
。我认为模型问题是因为它是这样的: message
< message_pictures
< message_pictures attachments
,但是(取决于你的 use-case),它可能应该就像 message
< message_pictures
- message_picture attachment
,或者只是 message
< message_pictures attachments