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

?

+1


source to share


1 answer


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

      

+1


source







All Articles