2016-07-27 1 views
2

변경 집합에 대해 두 속성 중 하나가 존재하는지 확인하는 가장 좋은 방법은 무엇입니까?Ecto validate_required 두 속성 중 하나

두 속성 중 어느 것도이

를 제공하는 경우 검증은 실패 예를 들어, 이메일 : 이름 : UID, 사용자의 속성을 가진 모델을 고려 전화

  • : 이메일이나 : UID가 존재한다는
  • : 이름은 항상
  • 중 하나
  • 을 가 필요로하는 전화는 선택 사항입니다

이 방법이 유용할까요?

def changeset(struct, params \\ %{}) do 
    struct 
     |> cast(params, [:name,:email,:uid,:phone]) 
     |> validate_required([:name, :email]) || validate_required([:name, :uid] 
    end 
    end 

답변

4

당신은 같은 뭔가를 시작할 수 있습니다 :

def changeset(struct, params \\ %{}) do 
    struct 
    |> cast(params, ~w(name email uid phone)a) 
    |> validate_required(:name) 
    |> validate_required_params(params) 
    end 
end 

def validate_required_params(changeset, %{"uid" => _}) do 
    changeset 
    |> validate_required(:uid) 
end 

def validate_required_params(changeset, %{"email" => _}) do 
    changeset 
    |> validate_required(:email) 
end 

def validate_required_params(changeset, _params) do 
    changeset 
    |> add_error(:params, "either :uid or :email is required") 
end 

하지만 당신은 uidemail 모두 제공하는 경우도 예를 들어 확인해야합니다. 그런 경우에는 무엇을 할 것인가?

+0

굉장! 감사! – Tilo

+0

그래서 매개 변수 맵에는 ​​항상 원자가 아닌 문자열 키가 있어야합니다. 맞습니까? 내 컨트롤러 테스트를 작성하는 데 문제가 있습니다. '{uid "=>"abc123 "} ' 오류가 발생했습니다 :'** (ArgumentError) '의'where '에 키워드 목록이 있어야합니다 : [{"uid ","abc123 " }]' – Tilo

+0

그것은 나머지 설계 방법에 따라 다릅니다. json 요청으로 변환되기 때문에 테스트에서 원자를 사용할 수있다. – squixy