{"__v":0,"_id":"567f60861037a50d00e915e2","initVersion":{"_id":"55da5710a955100d00def8eb","version":"1.0.0"},"project":"54348ec95b10711400c6c445","tags":[],"user":{"_id":"5435b410495d5d0800f3a603","username":"","name":"Lance Halvorsen"},"createdAt":"2015-12-27T03:52:38.957Z","changelog":[],"body":"# Phoenix 1.0.x to 1.1.0 upgrade instructions\n\nPlease use the gist if you have issues https://gist.github.com/chrismccord/557ef22e2a03a7992624\n\n## Deps\n\nUpdate your `phoenix`, `phoenix_html` deps, and if using ecto, update your `phoenix_ecto` dep\n\n```elixir\n# mix.exs\ndef deps do\n  [{:phoenix, \"~> 1.1\"},\n   {:phoenix_ecto, \"~> 2.0\"},\n   {:phoenix_html, \"~> 2.3\"},\n   ...]\nend\n```\n\nNow run `$ mix deps.update phoenix phoenix_html phoenix_ecto`\n\n\n## View / Template Changes\n\nThe `@inner` assign has been removed in favor of explicit rendering with `render/3` and the new `@view_module` and `view_template` assigns.\n\nIn your `web/templates/layout/app.html.eex` (and other layouts), replace:\n\n    <%= @inner %>\n    \nwith:\n\n    <%= render @view_module, @view_template, assigns %>\n\n\n## Ecto Changes\n\nEcto 1.1 has renamed `Ecto.Model` to `Ecto.Schema` and moved many Model functions to the `Ecto` module. Update your `web/web.ex` blocks:\n\n```diff\ndef model do\n  quote\n-   use Ecto.Model\n+   use Ecto.Schema\n\n+   import Ecto\n    import Ecto.Changeset\n    ...  \n  end \nend\n\ndef controller do\n  quote\n    ...\n    alias MyApp.Repo\n+   import Ecto\n    import Ecto.Query, only: [from: 1, from: 2]\n    ...  \n  end \nend\n\ndef channel do\n  quote\n    ...\n    alias MyApp.Repo\n+   import Ecto\n    import Ecto.Query, only: [from: 1, from: 2]\n    ...  \n  end \nend\n```\n\n## Gettext (optional)\n\nGettext has been added for internationalization and localization support.\nSee the [Gettext docs](http://hexdocs.pm/gettext/Gettext.html) for full details.\n\nTo add Gettext support to your application first add `:gettext` to your deps in `mix.exs`:\n\n```elixir\ndef deps do\n  [...,\n   {:gettext, \"~> 0.9\"},\n   ...]\nend\n```\n\nNext, in `mix.exs`, add the `:gettext` compiler to your `project` and `:gettext` to your `:applications` list in `application` list:\n\n```diff\ndef project do\n  [...,\n-  compilers: [:phoenix] ++ Mix.compilers,\n+  compilers: [:phoenix, :gettext] ++ Mix.compilers,\n  ...]\nend\n\ndef application do\n  [mod: {MyApp, []},\n-  applications: [:phoenix, :phoenix_html, :cowboy, :logger,\n-                 :phoenix_ecto, :postgrex]]\n+  applications: [:phoenix, :phoenix_html, :cowboy, :logger, :gettext,\n+                 :phoenix_ecto, :postgrex]]\nend\n```\n\nNext, run `$ mix deps.get`\n\nNow, create a `gettext.ex` file at `web/gettext.ex` with the following contents:\n\n\n```elixir\ndefmodule MyApp.Gettext do\n  @moduledoc \"\"\"\n  A module providing Internationalization with a gettext-based API.\n\n  By using [Gettext](http://hexdocs.pm/gettext),\n  your module gains a set of macros for translations, for example:\n\n      import MyApp.Gettext\n\n      # Simple translation\n      gettext \"Here is the string to translate\"\n\n      # Plural translation\n      ngettext \"Here is the string to translate\",\n               \"Here are the strings to translate\",\n               3\n\n      # Domain-based translation\n      dgettext \"errors\", \"Here is the error message to translate\"\n\n  See the [Gettext Docs](http://hexdocs.pm/gettext) for detailed usage.\n  \"\"\"\n  use Gettext, otp_app: :my_app\nend\n```\n\nReplace `MyApp` with your app module and `:my_app` with your otp app.\n\nNext run the following commands from your app root to add necessary gettext supporting files:\n\n```console\n$ mkdir -p priv/gettext/en/LC_MESSAGES\n$ curl https://raw.githubusercontent.com/phoenixframework/phoenix/277eb7dd03366b336458ffe8dbf637c133b595f0/installer/templates/new/priv/gettext/en/LC_MESSAGES/errors.po > priv/gettext/en/LC_MESSAGES/errors.po\n$ curl https://raw.githubusercontent.com/phoenixframework/phoenix/277eb7dd03366b336458ffe8dbf637c133b595f0/installer/templates/new/priv/gettext/errors.pot > priv/gettext/errors.pot\n```\n\nNext, create a `web/views/error_helpers.ex` and add these contents:\n\n```elixir\ndefmodule MyApp.ErrorHelpers do\n  @moduledoc \"\"\"\n  Conveniences for translating and building error messages.\n  \"\"\"\n  use Phoenix.HTML\n\n  @doc \"\"\"\n  Generates tag for inlined form input errors.\n  \"\"\"\n  def error_tag(form, field) do\n    if error = form.errors[field] do\n      content_tag :span, translate_error(error), class: \"help-block\"\n    end\n  end\n\n  @doc \"\"\"\n  Translates an error message using gettext.\n  \"\"\"\n  def translate_error({msg, opts}) do\n    # Because error messages were defined within Ecto, we must\n    # call the Gettext module passing our Gettext backend. We\n    # also use the \"errors\" domain as translations are placed\n    # in the errors.po file. On your own code and templates,\n    # this could be written simply as:\n    #\n    #     dngettext \"errors\", \"1 file\", \"%{count} files\", count\n    #\n    Gettext.dngettext(MyApp.Gettext, \"errors\", msg, msg, opts[:count], opts)\n  end\n\n  def translate_error(msg) do\n    Gettext.dgettext(MyApp.Gettext, \"errors\", msg)\n  end\nend\n```\n\nAnd now you can import `Gettext` and `MyApp.ErrorHelpers` into your `web.ex` `view` block:\n\n```diff\n      import MyApp.Router.Helpers\n+     import MyApp.ErrorHelpers\n+     import MyApp.Gettext\n```\n\n## ChangesetView changes\n\nChangests are no longer encoded to errors when encoding to JSON. The changeset errors should be rendered explicitly. Update your `web/views/changeset_view.ex` (if it exists) with the following code:\n\n```elixir\ndefmodule MyApp.ChangesetView do\n  use MyApp.Web, :view\n\n  @doc \"\"\"\n  Traverses and translates changeset errors.\n\n  See `Ecto.Changeset.traverse_errors/2` and\n  `MyApp.ErrorHelpers.translate_error/1` for more details.\n  \"\"\"\n  def translate_errors(changeset) do\n    Ecto.Changeset.traverse_errors(changeset, &translate_error/1)\n  end\n\n  def render(\"error.json\", %{changeset: changeset}) do\n    # When encoded, the changeset returns its errors\n    # as a JSON object. So we just pass it forward.\n    %{errors: translate_errors(changeset)}\n  end\nend\n```\n\nIf you are not using Gettext with the `ErrorHelpers` module, add this function to your `ChangesetView`:\n\n```elixir\ndef translate_error({msg, opts}) do\n  String.replace(msg, \"%{count}\", to_string(opts[:count]))\nend\ndef translate_error(msg), do: msg\n```\n\n## Channels JavaScript Client changes\n\n`after` hooks have been replaced by a timeout option on `push`, and a `receive(\"timeout\", callback)` hook.\n\n```javascript\n// 1.0.x\nchannel.push(\"new_message\", {body: \"hi!\"})\n       .receive(\"ok\", resp => console.log(resp) )\n       .after(5000, () => console.log(\"times! up\"))\n\nchannel.push(\"new_message\", {body: \"hi!\"})\n       .receive(\"ok\", resp => console.log(resp) )\n       .after(12000, () => console.log(\"times! up\"))\n\n// 1.1.0\n// timeout default to 5000\nchannel.push(\"new_message\", {body: \"hi!\"}) \n       .receive(\"ok\", resp => console.log(resp) )\n       .receive(\"timeout\", () => console.log(\"times! up\"))\n\n// custom timeout as optional 3rd arg\nchannel.push(\"new_message\", {body: \"hi!\"}, 12000)\n       .receive(\"ok\", resp => console.log(resp) )\n       .receive(\"timeout\", () => console.log(\"times! up\"))\n```","slug":"upgrading-from-v10-to-v11","title":"Upgrading from v1.0 to v1.1"}

Upgrading from v1.0 to v1.1


# Phoenix 1.0.x to 1.1.0 upgrade instructions Please use the gist if you have issues https://gist.github.com/chrismccord/557ef22e2a03a7992624 ## Deps Update your `phoenix`, `phoenix_html` deps, and if using ecto, update your `phoenix_ecto` dep ```elixir # mix.exs def deps do [{:phoenix, "~> 1.1"}, {:phoenix_ecto, "~> 2.0"}, {:phoenix_html, "~> 2.3"}, ...] end ``` Now run `$ mix deps.update phoenix phoenix_html phoenix_ecto` ## View / Template Changes The `@inner` assign has been removed in favor of explicit rendering with `render/3` and the new `@view_module` and `view_template` assigns. In your `web/templates/layout/app.html.eex` (and other layouts), replace: <%= @inner %> with: <%= render @view_module, @view_template, assigns %> ## Ecto Changes Ecto 1.1 has renamed `Ecto.Model` to `Ecto.Schema` and moved many Model functions to the `Ecto` module. Update your `web/web.ex` blocks: ```diff def model do quote - use Ecto.Model + use Ecto.Schema + import Ecto import Ecto.Changeset ... end end def controller do quote ... alias MyApp.Repo + import Ecto import Ecto.Query, only: [from: 1, from: 2] ... end end def channel do quote ... alias MyApp.Repo + import Ecto import Ecto.Query, only: [from: 1, from: 2] ... end end ``` ## Gettext (optional) Gettext has been added for internationalization and localization support. See the [Gettext docs](http://hexdocs.pm/gettext/Gettext.html) for full details. To add Gettext support to your application first add `:gettext` to your deps in `mix.exs`: ```elixir def deps do [..., {:gettext, "~> 0.9"}, ...] end ``` Next, in `mix.exs`, add the `:gettext` compiler to your `project` and `:gettext` to your `:applications` list in `application` list: ```diff def project do [..., - compilers: [:phoenix] ++ Mix.compilers, + compilers: [:phoenix, :gettext] ++ Mix.compilers, ...] end def application do [mod: {MyApp, []}, - applications: [:phoenix, :phoenix_html, :cowboy, :logger, - :phoenix_ecto, :postgrex]] + applications: [:phoenix, :phoenix_html, :cowboy, :logger, :gettext, + :phoenix_ecto, :postgrex]] end ``` Next, run `$ mix deps.get` Now, create a `gettext.ex` file at `web/gettext.ex` with the following contents: ```elixir defmodule MyApp.Gettext do @moduledoc """ A module providing Internationalization with a gettext-based API. By using [Gettext](http://hexdocs.pm/gettext), your module gains a set of macros for translations, for example: import MyApp.Gettext # Simple translation gettext "Here is the string to translate" # Plural translation ngettext "Here is the string to translate", "Here are the strings to translate", 3 # Domain-based translation dgettext "errors", "Here is the error message to translate" See the [Gettext Docs](http://hexdocs.pm/gettext) for detailed usage. """ use Gettext, otp_app: :my_app end ``` Replace `MyApp` with your app module and `:my_app` with your otp app. Next run the following commands from your app root to add necessary gettext supporting files: ```console $ mkdir -p priv/gettext/en/LC_MESSAGES $ curl https://raw.githubusercontent.com/phoenixframework/phoenix/277eb7dd03366b336458ffe8dbf637c133b595f0/installer/templates/new/priv/gettext/en/LC_MESSAGES/errors.po > priv/gettext/en/LC_MESSAGES/errors.po $ curl https://raw.githubusercontent.com/phoenixframework/phoenix/277eb7dd03366b336458ffe8dbf637c133b595f0/installer/templates/new/priv/gettext/errors.pot > priv/gettext/errors.pot ``` Next, create a `web/views/error_helpers.ex` and add these contents: ```elixir defmodule MyApp.ErrorHelpers do @moduledoc """ Conveniences for translating and building error messages. """ use Phoenix.HTML @doc """ Generates tag for inlined form input errors. """ def error_tag(form, field) do if error = form.errors[field] do content_tag :span, translate_error(error), class: "help-block" end end @doc """ Translates an error message using gettext. """ def translate_error({msg, opts}) do # Because error messages were defined within Ecto, we must # call the Gettext module passing our Gettext backend. We # also use the "errors" domain as translations are placed # in the errors.po file. On your own code and templates, # this could be written simply as: # # dngettext "errors", "1 file", "%{count} files", count # Gettext.dngettext(MyApp.Gettext, "errors", msg, msg, opts[:count], opts) end def translate_error(msg) do Gettext.dgettext(MyApp.Gettext, "errors", msg) end end ``` And now you can import `Gettext` and `MyApp.ErrorHelpers` into your `web.ex` `view` block: ```diff import MyApp.Router.Helpers + import MyApp.ErrorHelpers + import MyApp.Gettext ``` ## ChangesetView changes Changests are no longer encoded to errors when encoding to JSON. The changeset errors should be rendered explicitly. Update your `web/views/changeset_view.ex` (if it exists) with the following code: ```elixir defmodule MyApp.ChangesetView do use MyApp.Web, :view @doc """ Traverses and translates changeset errors. See `Ecto.Changeset.traverse_errors/2` and `MyApp.ErrorHelpers.translate_error/1` for more details. """ def translate_errors(changeset) do Ecto.Changeset.traverse_errors(changeset, &translate_error/1) end def render("error.json", %{changeset: changeset}) do # When encoded, the changeset returns its errors # as a JSON object. So we just pass it forward. %{errors: translate_errors(changeset)} end end ``` If you are not using Gettext with the `ErrorHelpers` module, add this function to your `ChangesetView`: ```elixir def translate_error({msg, opts}) do String.replace(msg, "%{count}", to_string(opts[:count])) end def translate_error(msg), do: msg ``` ## Channels JavaScript Client changes `after` hooks have been replaced by a timeout option on `push`, and a `receive("timeout", callback)` hook. ```javascript // 1.0.x channel.push("new_message", {body: "hi!"}) .receive("ok", resp => console.log(resp) ) .after(5000, () => console.log("times! up")) channel.push("new_message", {body: "hi!"}) .receive("ok", resp => console.log(resp) ) .after(12000, () => console.log("times! up")) // 1.1.0 // timeout default to 5000 channel.push("new_message", {body: "hi!"}) .receive("ok", resp => console.log(resp) ) .receive("timeout", () => console.log("times! up")) // custom timeout as optional 3rd arg channel.push("new_message", {body: "hi!"}, 12000) .receive("ok", resp => console.log(resp) ) .receive("timeout", () => console.log("times! up")) ```