Reputation: 93
I have a user model that has many completed tasks. Also I have user to user relationship for subscribing, following etc. actions. I am trying to render all user completed tasks, and completed tasks for users that the user are following. The problem is, when i'm adding the followed users completed tasks to the users completed task array, the user_id column is changed from the followed users id to the user id. This is pretty weird and don't have any idea what is causing this. Sorry if I couldn't explain it clearly.
Here's the codes:
user.rb
class User < ActiveRecord::Base
include BCrypt
before_create :generate_auth_token!
has_secure_password :validations => false
has_many :completed_tasks, dependent: :destroy
has_many :relationships, foreign_key: "follower_id",
class_name: "Relationship",
dependent: :destroy
has_many :followed_users, through: :relationships, :source => "followed"
has_many :reverse_relationships, foreign_key: "followed_id",
class_name: "Relationship",
dependent: :destroy
has_many :followers, through: :reverse_relationships
def generate_auth_token!
begin
self.auth_token = SecureRandom.hex
end while self.class.exists?(auth_token: auth_token)
end
end
completed_task.rb
class CompletedTask < ActiveRecord::Base
belongs_to :user
validates :user_id, :presence => true
end
completed_tasks_controller.rb Here in the @user.completed_tasks << user.completed_tasks the user_id values gets changed to @user.id
def index
if valid_auth_token?
@completed_tasks = @user.completed_tasks
@user.followed_users.each do |user|
@completed_tasks << user.completed_tasks
end
render file: "api/v1/completed_tasks/index.json.jbuilder", status: :ok
else
head :unauthorized
end
end
Upvotes: 0
Views: 205
Reputation: 84114
You're mutating the association (appending objects to it) and appending objects to a has_many
changes the foreign key
You could convert to an array by calling to_a
: adding objects to an array (as opposed to an association) won't change them
You could also do something like
@completed_tasks = @user.followed_users.inject(@user.completed_tasks) {|result, user| result + user.completed_tasks}
The main difference here is that instead of using <<
(which modifies arrays) I've used +
(which returns a new array containing the concatenation of its arguments)
Upvotes: 1