0

I have a rails model set up as:

class Master < ActiveRecord::Base
  belongs_to :user
  has_many :submasters
  serialize :subdocs, Array
end

It has a serialized array of submaster_docs which stores the id of the connected subdocs and my model for Subdocs is:

class Subdocs < ActiveRecord::Base
  belongs_to :user
end

Now I have a rails method which deletes a subdoc when user clicks on the delete button.

While deleting the Subdocs entries I want to remove the id of the Subdocs from Master also so that it doesn't try to create an association between them even after deleting Subdocs

My database entry of Master looks as follows:

<ActiveRecord::Relation [#<Master id: 3, user_id: 1, name: "Being Batman", description: "Every man who has lotted here over the centuries, ...", subdocs: ["5"]>]> 

Database entry of subdoc:

<ActiveRecord::Relation [#<Subdoc id: 5, user_id: 1, name: "subdoc1.pdf">]> 

Over here for example if a user deletes the subdoc 5 then I want to remove that value from subdocs array of all Master's

My method for deleting the subdocs is as follows:

def destroy
  @masters = {}
  @subdoc = Subdoc.find(params[:id])
  @masters = current_user.user.masters

  # Tried these methods to delete the value.
  # @subdocs = @masters.select { |t| t.subdocs.to_a - [params[:id]] }
  # @subdocs = @masters.each { |t| t[:subdocs] - params[:id] }   

  @subdoc.destroy
  return render :status => 200, :json => { :success => true }    
end

But this throws me the error: No Implicit conversion of String into Array

How can I correct this? Thanks!

2 Answers 2

2

You don't want to use an array here. Especially not a serialized array:

  • You have to scan a string to be able use the column in a query.
  • ActiveRecord associations are built to work with actual foreign key columns. So are relational databases.
  • You get no referential integrity.

So start by creating a migration rails g migration add_master_to_subdocs

class AddMasterToSubdocs < ActiveRecord::Migration[5.0]
  def change
    add_reference :subdocs, :master, foreign_key: true
    remove_column :subdocs, :user_id
  end
end

We are also removing the user_id column since it won't be needed:

class Master < ActiveRecord::Base
  belongs_to :user
  has_many :submasters
  has_many :subdocs
end

class Subdocs < ActiveRecord::Base
  belongs_to :master
  has_one :user, through: :master
end
Sign up to request clarification or add additional context in comments.

3 Comments

If you want a Subdoc to belong to many Masters then use a join table and declare the association as has_many :through.
Although what you're saying makes logical sense but I'm working on a legacy application and I'm not allowed to make changes to the database. I need to use the existing table and models to do this :/
I guess my only advice then is to run away from the project as fast you can.
0

While I agree with max and you should not use this architecture, assuming you keep it as is, you will need to delete the item from the array in master and save master.

def destroy
  @masters = {}
  @subdoc = Subdoc.find(params[:id])
  @masters = current_user.user.masters
  @masters.each do |master| 
    if master.subdocs.index(params[:id])
      master.subdocs.delete(params[:id])
      master.save!
    end
  end  

  @subdoc.destroy
  return render :status => 200, :json => { :success => true }    
end

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.