官术网_书友最值得收藏!

Creating our Option schema

We'll need to create an Option schema, just like we have the Poll schema, but we'll need to do some additional legwork to make sure our representation makes sense. We'll also need to go back and fix up one thing we omitted from our Poll schema! First, we want to name our module Vocial.Votes.Option instead of Vocial.Votes.Poll (for obvious reasons). Next, we'll need to alias both Vocial.Votes.Poll and Vocial.Votes.Option. This is because we need the sanity helper for referencing the struct of our Option schema, and also because we'll need to reference the Poll schema as well to define our relationship to that table. We'll also need to create a :votes column on the schema; this one should be an integer with a default value of 0. Let's take a look at the finished file with all of those bells and whistles:

defmodule Vocial.Votes.Option do
use Ecto.Schema
import Ecto.Changeset
alias Vocial.Votes.Option
alias Vocial.Votes.Poll

schema "options" do
field :title, :string
field :votes, :integer, default: 0

belongs_to :poll, Poll

timestamps()
end

def changeset(%Option{}=option, attrs) do
option
|> cast(attrs, [:title, :votes, :poll_id])
|> validate_required([:title, :votes, :poll_id])
end
end

We have our first example here of specifying options for the definitions of our fields via the votes field definition. Here, we're saying that the default value for any Option that gets created is a 0 in the votes column; this will make writing our insert statements a little easier and save us from wacky scenarios where an Option has nil votes or something like that. In addition, notice that we have a new statement here, the belongs_to statement. As mentioned earlier, we designed this as a has_many relationship between Polls and Options. Specifically, here we're saying that an Option belongs_to a Poll, so one thing we quickly need to do is return to our Poll schema and add a has_many statement to tell Ecto that there is another side to the association. We’ll add the following line to the top, near our other alias statement:

alias Vocial.Votes.Option

And we'll add the has_many statement inside of our schema block in the Poll schema:

has_many :options, Option

Let's go back to the IEx session that we tested our Poll schema in and try out our Options schema! First, we'll make sure we get a Poll back from our database by running Repo.all(Poll):

iex(4)> Repo.all(Poll)
[debug] QUERY OK source="polls" db=3.5ms decode=4.7ms
SELECT p0."id", p0."title", p0."inserted_at", p0."updated_at" FROM "polls" AS p0 []
[%Vocial.Votes.Poll{__meta__: #Ecto.Schema.Metadata<:loaded, "polls">, id: 1,
inserted_at: ~N[2017-10-05 20:18:08.931657], title: "Sample Poll",
updated_at: ~N[2017-10-05 20:18:08.933798]}]

We have a Poll with an ID of 1, so let's use that to create our options! We'll create two simple options, yes and no, so let's start by adding the alias for our Option schema:

iex(5)> alias Vocial.Votes.Option
Vocial.Votes.Option

And finally, let's insert changesets for our two new options using a poll_id of 1:

iex(6)> Option.changeset(%Option{}, %{title: "Yes", poll_id: 1}) |> Repo.insert()
[debug] QUERY OK db=0.2ms
begin []
[debug] QUERY OK db=5.6ms
INSERT INTO "options" ("poll_id","title","votes","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5) RETURNING "id" [1, "Yes", 0, {{2017, 10, 5}, {21, 14, 32, 58102}}, {{2017, 10, 5}, {21, 14, 32, 59711}}]
[debug] QUERY OK db=19.4ms
commit []
{:ok,
%Vocial.Votes.Option{__meta__: #Ecto.Schema.Metadata<:loaded, "options">,
id: 1, inserted_at: ~N[2017-10-05 21:14:32.058102],
poll: #Ecto.Association.NotLoaded<association :poll is not loaded>,
poll_id: 1, title: "Yes", updated_at: ~N[2017-10-05 21:14:32.059711],
votes: 0}}
iex(7)> Option.changeset(%Option{}, %{title: "No", poll_id: 1}) |> Repo.insert()
[debug] QUERY OK db=0.3ms
begin []
[debug] QUERY OK db=7.1ms
INSERT INTO "options" ("poll_id","title","votes","inserted_at","updated_at") VALUES ($1,$2,$3,$4,$5) RETURNING "id" [1, "No", 0, {{2017, 10, 5}, {21, 15, 3, 797493}}, {{2017, 10, 5}, {21, 15, 3, 797517}}]
[debug] QUERY OK db=6.2ms
commit []
{:ok,
%Vocial.Votes.Option{__meta__: #Ecto.Schema.Metadata<:loaded, "options">,
id: 2, inserted_at: ~N[2017-10-05 21:15:03.797493],
poll: #Ecto.Association.NotLoaded<association :poll is not loaded>,
poll_id: 1, title: "No", updated_at: ~N[2017-10-05 21:15:03.797517],
votes: 0}}

This time we took a slightly different route and piped the results of the changeset call directly into the Repo.insert() function via the pipeline operator! We need to verify that this added the options to our Poll object, so let's fetch our Poll out of the database:

iex(11)> poll = Repo.get!(Poll, 1)
[debug] QUERY OK source="polls" db=3.2ms
SELECT p0."id", p0."title", p0."inserted_at", p0."updated_at" FROM "polls" AS p0 WHERE (p0."id" = $1) [1]
%Vocial.Votes.Poll{__meta__: #Ecto.Schema.Metadata<:loaded, "polls">, id: 1,
inserted_at: ~N[2017-10-05 20:18:08.931657],
options: #Ecto.Association.NotLoaded<association :options is not loaded>,
title: "Sample Poll", updated_at: ~N[2017-10-05 20:18:08.933798]}
主站蜘蛛池模板: 会同县| 扶绥县| 东海县| 蒙山县| 淮安市| 安陆市| 景德镇市| 霸州市| 洛扎县| 上栗县| 阿克陶县| 黔江区| 建湖县| 贡嘎县| 清徐县| 无棣县| 旬邑县| 寿阳县| 海阳市| 古浪县| 耿马| 宜都市| 东莞市| 永登县| 教育| 托克逊县| 搜索| 甘德县| 合水县| 清河县| 阿图什市| 崇文区| 大竹县| 梓潼县| 永福县| 保亭| 涞源县| 乌鲁木齐市| 阿图什市| 河池市| 桓台县|