다음과 같은 변경 세트가 있습니다.
%{
creator_id: "4",
name: "a test with GraphQL",
place_id: "13",
entree_id: "8",
base: "wheat",
type: "food"
}
내 ecto 스키마는 다음과 같습니다.
schema "items" do
field :type, :string
field :name, :string
field :data, :map
belongs_to :creator, Name.SubName.Creators
belongs_to :place, Name.SubName.Places
belongs_to :entree, Name.SubName.Entrees
timestamps()
end
당신이 볼 수 있듯이 base
체외 스키마에있는 필드 아니다, 나는 캐스트하려는 base
에 data
그것이이되도록 필드 map
유형, 즉 : {"base":"wheat"}
. 여기서는 단일 테이블 상속을 사용하고 있습니다.
내 items
테이블에 레코드를 추가하려고 합니다. 지금 테이블에서 읽을 때 data
필드를 type
내 base
필드 를 포함 하는 포함 된 스키마 (에 따라 다름)로 캐스팅합니다 . 내가 고생하는 곳은이 필드를 데이터베이스로 되 돌리는 것입니다.
나는 비슷한 것을 사용해 Ecto.Changeset.cast(params[:base], Map.keys(%{data: :map}))
보았지만 분명히 유효한지도가 아닌 값을 얻었습니다. 또한 이것은 각각을 나타내는 다른 포함 된 스키마와 연결된 모든 고유 필드를 지정하는 것이 어려울 것 type
입니다.
embeds_one
및 embeds_many
때문에이 상황에 적용되지 않습니다 data
체외 필드는 다른 포함 된 스키마 유형을 나타냅니다. 따라서이 경우 내 질문은 임베디드 스키마 사용에 관한 것이 아니라 a에서 특정 필드를 선택 changeset
하여 map
. 내 절반은 각각에 대해 별도의 테이블을 만들어야한다고 생각 type
하면 걱정할 필요가 없습니다.
다음을 사용할 수 있습니다 Map.split/2
.
@required_fields [:name, :type, :creator_id, :place_id, :entree_id]
@all_fields [:data | @required_fields]
def changeset(struct, params) do
{allowed, others} = Map.split(params, @required_fields)
params = Map.put(allowed, :data, others)
struct
|> cast(params, @all_fields)
|> # ...
end
여기서 주목해야 할 중요한 점은이 예제는 아톰 키가있는 맵에서만 작동한다는 것입니다. 문자열과 아톰 키를 모두 사용하려면 약간 수정해야합니다. 에 대한 기본값으로 빈지도를 지정하는 것도 고려할 수 있습니다 :data
.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다