Как использовать вложенные формы ассоциаций в Фениксе? - PullRequest
0 голосов
/ 28 июня 2018

Итак, я в настоящее время изучаю Феникс 1.3 и хочу изучать экто-ассоциации. Я использую Angularjs для внешнего интерфейса

У меня есть две схемы user.ex и profile.ex

Оба сгенерированы mix phx.gen.json

user.ex

schema "users" do
field(:password_hash, :string)
field(:username, :string)
# Virtual fields:
field(:password, :string, virtual: true)
field(:password_confirmation, :string, virtual: true)
# this was added
has_one(:profiles, AuthApp.Accounts.Profile)

timestamps()end

profile.ex

schema "profiles" do
field :firstname, :string
field :lastname, :string
field :photo, :string
field :user_id, :id
belongs_to :user, AuthApp.Accounts.User  # this was added

timestamps()end

профиль контроллера

def create(conn, %{"profile" => profile_params}) do
with {:ok, %Profile{} = profile} <- Accounts.create_profile(profile_params) do
  conn
  |> put_status(:created)
  |> put_resp_header("location", profile_path(conn, :show, profile))
  |> render("show.json", profile: profile)
endend

Моя проблема в том, что я не знаю, какому контроллеру я должен добавить ассоциации и как он будет выглядеть.

1 Ответ

0 голосов
/ 28 июня 2018

Это действительно ваше дело, вы можете сделать это обоими способами! Тем не менее, некоторые рекомендации / советы по передовому стилю для этого конкретного сценария.

Если функция вашего приложения / страница / и т. Д. Работает в основном с одним из этих объектов домена, используйте этот контроллер.

Например, если вы отображаете страницу профиля и предлагаете различные маршруты внутри нее, или загружаете различные фрагменты данных для заполнения профиля и включения связанных с ним функций, тогда имеет смысл возвращать вложенный ответ API, представляющий взаимосвязь данных. с профилем на верхнем уровне.

Я бы обычно делал что-то вроде этого (начиная с того места, где вы остановились с определенными схемами и отношениями): Подберите связанные данные, которые я хочу для моего запроса API профиля в ProfileController. Я обычно делаю это с помощью функции Context, которая обрабатывает предварительную загрузку отношений. В этом случае эта комбинация может выглядеть примерно так:

def show(conn, %{"id" => id}) do
  profile = Accounts.get_profile!(id)
  render(conn, "show.html", profile: profile)
end

Предполагая что-то вроде контекста Account для хранения схемы Profile, где Account.get_profile! / 1 выглядит примерно так:

def get_profile!(id) do
  query =
    from(p in Account.Profile,
      where: p.user_id == ^id,
      select: p,
      preload: [:user]
    )

  YourApp.Repo.get(query)
end

В результате ответ API выглядит примерно так:

profile : {
  photo: {},
  user: {
    id: "1"
  }
}

С которой удобно работать при приближении с точки зрения включения функций профиля.

Однако пара предостережений:

  1. Я обычно выполняю загрузку основной пользовательской информации в приложение через conn.assigns, сессию и плагин или некоторый уровень кэша, если использую токен на основе аутентификации. Если у вас есть шанс, в книге Programming Phoenix есть отличные примеры этого подхода начального уровня, а в библиотеке Guardian есть хорошая информация о подходе на основе токенов.

  2. Если вы соответствуете определенному стандарту API, там будут рекомендации и лучшие практики, поэтому поищите «REST» или «GraphQL», когда X даст полезную информацию.

  3. Я проигнорировал все, что касается аутентификации / авторизации и т. Д., Но преимущество выполнения (1) заключается в том, что вы можете безопасно обрабатывать запросы API, чтобы пользователь не мог просто запросить другой идентификатор профиля у своего (который происходит при выполнении запроса базового профиля и предварительной загрузке всей пользовательской информации).

...