Moving static data from db to code in rails 3
Let's say I have a simple scenario with two models, Book
and Category
s, where each book has and belongs to many categories.
I want to transfer data Category
from database according to here and.
My category class looks like this:
class Category
FICTION = Category.new(1, 'Fiction')
NON_FICTION = Category.new(2, 'Non Fiction')
CONTUTERS = Category.new(3, 'Contuters')
def initialize(id, name)
@id = id
@name = name
end
end
I have a table books_categories
like this:
| book_id | category_id |
| 1 | 1 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
...
How should I model this in my book class and in db?
Ideally I would like it to look like this:
class Book < ActiveRecord::Base
has_many :categories
end
But where the book can be added or removed from the categories.
One approach is to use built-in associations . What I don't like about this is that it makes the db difficult to test.
Are there any other approaches possibly supporting the existing table books_categories
?
source to share
I looked at https://github.com/pboling/flag_shih_tzu but in the end I implemented this with a simple connection model has_many
. I added a column id
to the table books_categories
, renamed to book_categories
and implemented custom getters / setters to Book
:
class Category
ALL = [
FICTION = Category.new(1, 'Fiction'),
NON_FICTION = Category.new(2, 'Non Fiction'),
CONTUTERS = Category.new(3, 'Contuters'),
]
CATEGORIES_BY_ID = ALL.index_by(&:id)
def initialize(id, name)
@id = id
@name = name
end
end
class BookCategory < ActiveRecord::Base
def category
Category::CATEGORIES_BY_ID[category_id]
end
end
class Book < ActiveRecord::Base
has_many :book_categories, :autosave => true
def categories
book_categories.map(&:category)
end
def category_ids
book_categories.map(&:category_id)
end
def category_ids=(ids)
ids = ids.reject(&:blank?)
book_categories.each do |book_category|
book_category.mark_for_destruction unless ids.include?(book_category.id)
end
(ids - category_ids).each do |new_id|
book_categories.build(category_id: new_id)
end
end
end
source to share