2016-12-01 7 views
1

У меня есть родительский и дочерний компоненты. Я хотел бы создать родительский элемент одновременно с дочерним, потому что родитель не может существовать без дочернего элемента. В частности у меня есть subscriptions, который has_manyservicesСоздайте родительскую, дочернюю вложенную связь с требуемым foreign_id одновременно в Ecto

Если мой ребенок модель имеет требуемое поле является иностранное ограничение, как я создаю обе модели одновременно? Я получаю сообщение об ошибке в моем наборе изменений, указывающее, что parent.id не может быть пустым.

Я знаю, что могу сделать Repo.insert!(Subscription), а затем создать Service changeet с subscription.id, но мне было интересно, можно ли создавать оба одновременно?

Мои родительские и дочерние ревизиями перечислены ниже:

Родитель (Подписка)

def changeset(struct, params \\ %{}) do 
# get the current time and add 30 days. 
    {:ok, active_until} = DateTime.utc_now() 
     |> DateTime.to_unix() |> Kernel.+(2592000) |> DateTime.from_unix() 

    struct 
    |> change(active_until: active_until) 
    |> cast(params, [:active_until, :user_id]) 
    |> cast_assoc(:services) 
    |> validate_required([:active_until]) 
end 

ребенка (службы)

def changeset(struct, params \\ %{}) do 
    struct 
    |> cast(params, [:start_time, :frequency, :subscription_id]) 
    |> validate_required([:subscription_id]) 
    |> foreign_key_constraint(:subscription_id) 
end 
+0

Какое поле в подписке зависит от службы здесь? И можете ли вы отправить точное сообщение об ошибке? – Dogbert

ответ

1

Это проблема яйца курица: уникальный ID присваивается основной записи базой данных движком. Таким образом, это невозможно выполнить в одной транзакции.

Единственная возможность будет обрабатывать ID ключ на мастер-таблицы самостоятельно, с помощью внутренней функции DB для генерации GUID (как UUID() в MySQL или CREATE SEQUENCE в PostgreSQL.) В этом случае можно было бы назвать эту функцию заранее и установите явно ID.

Я бы не рекомендовал последний подход.

0

Это старый вопрос, но, отвечая на случай, если кто-то еще приземляется здесь, как я.

def changeset(%Subscription{} = subscription, attrs) do 
    subscription 
    |> cast(attrs, [...]) 
    |> ... 
    |> cast_assoc(:services, required: true) 
    |> ... 
end 

def create_subscription(attrs \\ %{}) do 
    %Subscription{} 
    |> Subscription.changeset(attrs) 
    |> Repo.insert() 
end 

Это должно сделать работу

 Смежные вопросы

  • Нет связанных вопросов^_^