2016-01-07 2 views

ответ

4

Есть несколько способов сделать это. Один из них требует мастера эктопаразитов (скоро будут Ecto v2.0) и простое обновление родителя непосредственно:

# Assuming a child_changeset with the parent loaded 
child_changset = Ecto.Changeset.put_assoc(child_changeset, :parent, %{updated_at: Ecto.DateTime.utc}) 

Теперь, когда ребенок сохраняется, она будет автоматически распространяться изменениями родителя.

В качестве альтернативы, вы можете использовать экто v1.1 с prepare_changes и update_all для распространения изменений:

# Assuming a child_changeset 
Ecto.Changeset.prepare_changes child_changeset, fn changeset -> 
    query = Ecto.assoc(changeset.model, :parent) 
    changeset.repo.update_all query, set: [updated_at: ^Ecto.DateTime.utc] 
    changeset 
end 

В этом примере мы используем prepare_changes, который выполняется в транзакции вместе с детьми, чтобы изменения строить запрос, представляющий родительскую модель, и выпуск update_all, обновляющий все столбцы updated_at для модулей, соответствующих запросу.

1

Вы можете добавить функцию в набор изменений, который проверяет наличие изменений и если они действительны (это если вы обновляете ассоциации через родительский набор изменений).

def touch_parent(%{changes: changes, valid: true}=changeset) when map_size(changes) > 0 do 
    updated_at = DateTime.utc_now() |> DateTime.to_naive() 
    cast(changeset, %{updated_at: updated_at}, [:updated_at]) 
end 
def touch_parent(changeset), do: changeset 

Вы можете положить, что в конце вашей update_changeset функции для модели.

def update_changeset(%Model{}=model, attrs) do 
    model 
    # casting 
    |> touch_parent() 
end 

Если вы хотите просто сделать определенные ассоциации вы могли бы сделать что-то вроде этого:

def touch_parent(%{changes: changes, valid: true) when map_size(changes) > 0 do 
    updated_at = DateTime.utc_now() |> DateTime.to_naive() 
    changed_fields = Map.keys(changes) 
    cond do 
    :association in changed_fields -> 
     cast(changeset, %{updated_at: updated_at}, [:updated_at]) 
    true -> changeset 
    end 
end 

:)