Issue
I have
message table
and
message_pictures
table(It belongs to the message table) and what I want to do is retrieve each messsge pictures (if there is any) from the
message_controller
.
How can I do it. I have surfed the web but found little scanty explanations on it.
This is the message class(model)
class Message < ApplicationRecord
belongs_to :user
has_many :message_pictures, dependent: :destroy
accepts_nested_attributes_for :message_pictures
end
This is the message_pictures class(model)
class MessagePicture < ApplicationRecord
belongs_to :message, optional: true
mount_uploader :message_pictures, PictureUploader
end
and this is the index method of the message_controller class
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
You can see the line 4 of the index method to see the way I did mine but its not working
Solution
I believe what you need is 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
simplifies the retrieving of "nested" children records via "SQL JOINS", of which normally you would have done it in a longer (more explicit way) like the following (which also works):
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
Update: Alternative Solution
Looking back at your question, I have a feeling you'd only want @message_pictures
that corresponds to @messages
and not to all@user.messages
, because I noticed you have pagination for the messages. I'll do it like this instead:
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 (example)
<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 %>
^ Above assumes MessagePicture
is using carrierwave
. P.S. It looks to me there's something wrong with how you defined your models, because your message
has many message_pictures
, while each of the message_picture
also has many attached message_picture
carrierwave attachments (assuming you used the "multiple-file" upload set up for carrierwave because you used mount_uploader :message_pictures, PictureUploader
instead of mount_uploader :message_picture, PictureUploader
. The model problem I think is because it's like this: message
< message_pictures
< message_pictures attachments
, but (depending on your use-case), it should probably be just like message
< message_pictures
- message_picture attachment
, or just simply message
< message_pictures attachments
Answered By - Jay-Ar Polidario Answer Checked By - Katrina (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.