Does this fix in Ecto 2.0.6? I have similar issue. The major difference is that one table use composite primary key. The schema of my legacy system blows my mind.
MySQL 5.6
defmodule Jpos.Role do
use Jpos.Web, :model
@primary_key {:secroleid, :id, autogenerate: true}
@derive {Phoenix.Param, key: :secroleid}
schema "securityroles" do
field :secrolename, :string
field :is_synchronized_sale_point, :boolean, default: false
field :modulesallowed, :string
has_many :users, Jpos.User, foreign_key: :fullaccess, references: :secroleid
has_many :security_groups, Jpos.SecurityGroup, foreign_key: :secroleid, references: :secroleid
has_many :groups_tokens, through: [:security_groups, :token]
end
defmodule Jpos.SecurityToken do
use Jpos.Web, :model
@primary_key {:tokenid, :id, autogenerate: false}
@derive {Phoenix.Param, key: :tokenid}
schema "securitytokens" do
field :tokenname, :string
field :moudule_index, :integer
has_many :security_groups, Jpos.SecurityGroup, references: :tokenid, foreign_key: :tokenid
end
defmodule Jpos.SecurityGroup do
use Jpos.Web, :model
@primary_key false
schema "securitygroups" do
belongs_to :role, Jpos.Role, references: :secroleid, foreign_key: :secroleid, primary_key: true
belongs_to :token, Jpos.SecurityToken, references: :tokenid, foreign_key: :tokenid, primary_key: true
field :add_flag, :boolean, default: false
field :edit_flag, :boolean, default: false
field :delete_flag, :boolean, default: false
field :audit_flag, :boolean, default: false
field :process_flag, :boolean, default: false
end
iex log =>
iex(7)> role |> Repo.preload(:groups_tokens)
[debug] QUERY OK source="securitygroups" db=1.8ms decode=2.8ms
SELECT s0.`secroleid`, s0.`tokenid`, s0.`add_flag`, s0.`edit_flag`, s0.`delete_flag`, s0.`audit_flag`, s0.`process_flag`, s0.`secroleid` FROM `securitygroups` AS s0 WHERE (s0.`secroleid` = ?) ORDER BY s0.`secroleid` [30]
[debug] QUERY OK source="securitytokens" db=2.2ms decode=1.5ms queue=0.1ms
SELECT s0.`tokenid`, s0.`tokenname`, s0.`moudule_index`, s0.`tokenid` FROM `securitytokens` AS s0 WHERE (s0.`tokenid` IN (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)) [1, 15, 101100, 101102, 101103, 101105, 101200, 101201, 101202, 101203, 101204, 101207, 101209, 101212, 101300, 101301, 101302, 101401, 101402, 101405, 101406, 101407, 101409, 101422, 101423, 101424, 101506, 101600, 101601, 101602, 101604, 101605, 101606, 101607, 101608, 101609, 101610, 101611, 101612, 101613, 101614, 101615, 101616, 101617, 101618, 101619, 101620, 101621, 101622, 101623, ...]
** (ArgumentError) cannot preload through association `groups_tokens` on `Jpos.Role` because custom query did not return a map.
When preloading through associations, the custom query must always return a map with at least all primary keys, got: `%Jpos.SecurityToken{__meta__: #Ecto.Schema.Metadata<:loaded, "securitytokens">, moudule_index: 0, security_groups: #Ecto.Association.NotLoaded<association :security_groups is not loaded>, tokenid: 1, tokenname: "訂單輸入/查詢及客戶資料存取"}`
(elixir) lib/enum.ex:1184: Enum."-map/2-lists^map/1-0-"/2
(elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
(stdlib) erl_eval.erl:669: :erl_eval.do_apply/6
(iex) lib/iex/evaluator.ex:135: IEx.Evaluator.handle_eval/6
(iex) lib/iex/evaluator.ex:128: IEx.Evaluator.do_eval/4
(iex) lib/iex/evaluator.ex:108: IEx.Evaluator.eval/4
(iex) lib/iex/evaluator.ex:27: IEx.Evaluator.loop/3