t56k
t56k

Reputation: 6981

Rails: changing from three columns in a table to one

I am modifying a Documents table from using three columns (article1, article2, and article3) to one (articles) which has a string of comma-separated IDs stored in it (i.e., 23,4,33,2). That's all working well, but I'm trying to adjust the functions that read the three columns to read the one and I'm getting rather stuck.

In the model I have:

scope :all_articles, lambda {|p| where(:page => p) }

In the controller I have this:

@articles = (1..3).to_a.map { |i| Article.all_articles(i).reverse }

And in the view:

<% @articles.each_with_index do |a, i| %>
  <%= a[i].name %>
<% end %>

It's just a bit beyond me at this point.

Cheers!

Upvotes: 0

Views: 49

Answers (1)

Sean Hill
Sean Hill

Reputation: 15056

It's usually not good practice to put store the ids in a column like you have done. It is better to break that relationship out into a Has and Belongs to Many relationship. You set it up in your models like this:

class Document < ActiveRecord::Base
  #...
  has_and_belongs_to_many :articles
  #...
end

class Article < ActiveRecord::Base
  #... 
  has_and_belongs_to_many :documents
end

Then you will create a join table that ActiveRecord will use to store the relationships.

create_table :articles_documents, :id => false do |t|
  t.integer :article_id
  t.integer :document_id
end

add_index :articles_documents, [:article_id, :document_id], unique: true

This will allow you to query a lot more efficiently than you are currently doing. For example, to find all documents that have some article id. You would do:

@documents = Document.joins(:articles).where("articles.id = ?", some_article_id)

Or if you want to query for a document and return the articles with it:

@documents = Document.includes(:articles).where(some_conditions)

Upvotes: 1

Related Questions