Reputation: 564
I would like to use the includes method with the related element of my Post
My Post can be associated with different type of element. And I use a value :cat to knows witch kind of element is associated.
The value work as this (cat: (1 => Message, 2=>Question, 3=>Task, 4=>Event) with the association has_one
Example : If post.cat == 3, I can call the task related with a method post.task
Now, I would like to optimize the SQL requests of my Post/Index with the method includes. But is not working for the moment. Can you help me to find the error of my code ?
Post_controller :
def index
@posts = current_user.posts
@posts.each do |post|
if post.cat == 3
@task = post.task.includes(:users)
elsif post.cat == 4
@event = post.event.includes(:reminds)
end
end
end
Error: undefined method `includes'
Edit :
Post_model:
class Post < ApplicationRecord
has_one :post_message, dependent: :destroy
has_one :question, dependent: :destroy
has_one :task, dependent: :destroy
has_one :event, dependent: :destroy
end
Task_model :
class Task < ApplicationRecord
belongs_to :post
has_many :users_task, dependent: :destroy
has_many :users, through: :users_task
end
Upvotes: 2
Views: 110
Reputation: 564
Well, after many tries, I opted for a scope method to run the includes method. It's not a really elegant solution, but I think it's the best in my case.
So I'm preparing the scopes in my Post_Model:
scope :with_tasks, -> { where(cat: 3).includes(:user).includes(task: :users) }
scope :with_events, -> { where(cat: 4).includes(:user).includes(event: :reminds) }
And after, I render them in my index action like this :
@posts = current_user.posts.with_tasks + current_user.posts.with_events
So the code is generating 2 SQL Requests to find the posts (one for each category).
I think there is a way to join all that directly into a new global scope, but I don't know how. So if there is anyone knows that, he can edit the answer
Enjoy !
Upvotes: 2
Reputation: 607
Why are you using @posts.each ?
For me, the best solution for that is to find all the posts whith the defined cat to run the includes method. In your case, it would be like that :
@posts.where(cat: 1).includes(:message)
@posts.where(cat: 2).includes(:question)
@posts.where(cat: 3).includes(task: :users)
@posts.where(cat: 4).includes(event: :reminds)
Upvotes: 2
Reputation: 755
If you're getting an undefined method: 'includes'
error, it means that either post.task
or post.event
are not returning ActiveRecord objects like your code is expecting. Are you sure there will always be values set for .task
or .event
at that point in execution? Are there any cases where that value might be nil
or blank?
By the way, have you heard about 'polymorphic associations'? Defining an association as polymorphic allows you to associate records of arbitrary types with a specific column (by storing both object ID and class name on each record behind the scenes). It seems like this exactly matches your use case. It would be much easier to use the built-in mechanism than trying to do all the if-then switching based on category in your code.
Upvotes: -1