Подпишитесь на рассылку о самых интересных материалах в мире веб-разработки :)

Вопрос по коду .


(Дмитрий) #1

Добрый вечер. Недавно начал работать в Ruby on rails.
Я пытаюсь сделать список в котором задачи можно сортировать по категориям. Категории тоже можно создавать отдельно.
Обычный список сделать не проблема, но когда я пытаюсь расширить функционал мне стало непонятно как в таблице под каждым title записывать любое произвольное количество строк description? Можно ли в таблице todos в строке title создать таблицу c description ? Или же можно добавлять строки используя add_column?

class CreateTodos < ActiveRecord::Migration[5.1]
def change
create_table :todos do |t|
t.string :title
t.string :description
t.timestamps
end
end
end


(Kvokka) #2

1- научись форматировать код, прочитав правила форума
2- можно, для этого вместо типа string заюзай тип text. так же почитай про limit для этого типа данных.


(Сергей) #3

Мне вообще кажется человек хочет has_many :descriptions ))))


(Виктор) #4

Надо понять, что:

  1. title это не строка. Т. е. “произвольное количество строк” не “пишется под тайтл”, а в одной колонке записи (строки БД) тайтл, во второй колонке - дескрипшен.
  2. Строка базы данных и строка текста, это разные вещи. Сделайте, как говорит kvokka, и вы сможете добавить довольно большое количество строк текстовой информации к своему тайтлу, обойдясь при этом одной записью (строкой) базы данных.
    Другой разговор, когда у вас для одного тайтла может быть несколько разных дескрипшенов.

(Дмитрий) #5

Спасибо ребят, уже все решил. Список в котором можно создавать категории задач и добавлять сами задачи в любую категорию https://github.com/EckZar/todos

Сейчас меня волнует другой вопрос. Как загрузить в БД уже готовую таблицу из *.yml. Пытаюсь сделать через seed.rb но не совсем понимаю как правильно описать код после загрузки файла. Может кто что подскажет?


#6

Дима привет, вот рабочий пример для seed. Только учти, нужно выбрать один вариант “Seed Todo model”. В первом случае объекты будут созданы просто по списку из todo_list и если ты запустишь rake db:seed два раза, он продублирует все записи. Во втором примере итерации, производится проверка по title и если в базе уже есть такой объект, пропускает создание оного.

# Item list
todo_list = [
  {
    title: 'Lorem title one',
    description: 'Lorem description one'
  },
  {
    title: 'Lorem title two',
    description: 'Lorem description two'
  },
  {
    title: 'Lorem title three',
    description: 'Lorem description three'
  }
]

# Seed Todo model
todo_list.each do |item|
  Todo.create(item)
end

# Seed Todo model with unique title
todo_list.each do |item|
  Todo.find_by(title: item[:title]) || Todo.create(item)
end

Далее у тебя два варианта: ты можешь потратить время на ручной перенос данных из yml в хеш todo_list, или найти решение для парсинга yml в хеш программным методом. Я советую хотя бы попробовать второе :slight_smile:

P.s. Не вижу в миграции ассоциацию к категориям. Эту задачу можно решить без сторонних гемов: используя has_many, если todo должен принадлежать только к одной категории, или has_and_belongs_to_many если todo может принадлежать сразу нескольким категориям.


(Дмитрий) #7

Согласен, второй вариант гораздо лучше.

Но мой yml файл выглядит таким образом :

Projects:

  • title: 'one’
    todos:

    • text: 'text’
      isCompleted: false
    • text: 'text’
      isCompleted: false
  • title: 'two’
    todos:

    • text: 'text’
      isCompleted: false
    • text: 'text’
      isCompleted: false
    • text: 'text’
      isCompleted: false
  • title: 'three’
    todos:

    • text: 'text’
      isCompleted: false
    • text: 'text’
      isCompleted: false

Я перепробовал уже много способов, но иногда даже если rake db:seed проходит база все равно не заполняется.


#8

Судя по yml ассоциация has_many все же есть, тогда seed с загрузкой только новых объектов будет выглядеть так:

# List with Projects and Todo items
item_list = [
  {
    title: 'Project title one',
    todo_list: [
      {
        text: 'Todo text one',
        isCompleted: false
      },
      {
        text: 'Todo text two',
        isCompleted: false
      },
      {
        text: 'Todo text three',
        isCompleted: false
      }
    ]
  },
  {
    title: 'Project title two',
    todo_list: [
      {
        text: 'Todo text one',
        isCompleted: false
      },
      {
        text: 'Todo text two',
        isCompleted: false
      }
    ]
  },
]

# Seed Project model
item_list.each do |project|
  Project.find_by(title: project[:title]) || Project.create(title: project[:title])
end

# Seed Todo model
item_list.each do |project|
  current_project = Project.find_by(title: project[:title])
  project[:todo_list].each do |todo|
    current_project.todos.find_by(text: todo[:text]) || current_project.todos.create(todo)
  end
end

Seed Project model:
Тут мы проходим первый раз по item_list и создаем project, если его нет в базе.

Seed Todo model:
Проходимся по item_list второй раз. Сначала находим текущий project в базе, далее разбираем todo_list и создаем оные с учетом ассоциации к текущему project. Опять же, добавляются только новые todo.