samiljin
samiljin

Reputation: 93

Adding records to activerecord array changes attribute value

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

Answers (1)

Frederick Cheung
Frederick Cheung

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

Related Questions