如何使error
变量始终等于字符串?在几乎所有情况下,它都为零,并且永远不应为零。在所有有字符串的情况下,我都想使error
等于该字符串:
error = if user_product do
if user_product.voted_not_vegan && report do
"Whoops! You have already reported this product is not vegan"
end
if !user_product.voted_not_vegan && report do
changeset =
UserProduct.changeset(
user_product,
%{:voted_not_vegan => true}
)
case Api.Repo.update(changeset) do
{:ok, product} -> IO.puts("error")
{:error, changeset} -> IO.puts("error")
end
"Success! Reported not vegan"
changeset =
Product.changeset(
product,
%{:not_vegan_count => not_vegan_count + 1}
)
case Api.Repo.update(changeset) do
{:ok, product} -> IO.puts("error")
{:error, changeset} -> IO.puts("error")
end
end
IO.inspect(user_product, label: "userproduct")
IO.inspect(confirm, label: "confirm")
if user_product.voted_vegan && confirm do
"Whoops! You have already confirmed this product is vegan"
end
if !user_product.voted_vegan && confirm do
changeset =
Product.changeset(
product,
%{:vegan_count => vegan_count + 1}
)
case Api.Repo.update(changeset) do
{:ok, product_shop} -> IO.puts("error")
{:error, changeset} -> IO.puts("error")
end
"Success! Confirmed is vegan"
changeset =
UserProduct.changeset(
user_product,
%{:voted_vegan => true}
)
case Api.Repo.update(changeset) do
{:ok, product} -> IO.puts("error")
{:error, changeset} -> IO.puts("error")
end
end
else
IO.puts("insert user product")
UserProduct.insert_user_product(conn, %{
p_id: String.to_integer(pid),
u_id: uid,
voted_not_vegan: report,
voted_vegan: confirm
})
user_product =
from(up in UserProduct,
where: up.u_id == ^uid,
where: up.p_id == ^pid
)
|> Api.Repo.one()
if report do
changeset =
Product.changeset(
product,
%{:not_vegan_count => not_vegan_count + 1}
)
case Api.Repo.update(changeset) do
{:ok, product} -> IO.puts("error")
{:error, changeset} -> IO.puts("error")
end
changeset =
UserProduct.changeset(
user_product,
%{:voted_not_vegan => true}
)
case Api.Repo.update(changeset) do
{:ok, product} -> IO.puts("error")
{:error, changeset} -> IO.puts("error")
end
"Success! Reported not vegan"
end
下面是我对@Aleksei Matiushkin的回答的实现。尽管可能已经偏离了答案,但它似乎正在起作用。
@spec check_user_product(
usr_prduct :: %UserProduct{},
{report :: boolean(), confirm :: boolean()},
product :: %Product{}
) :: any()
defp check_user_product(user_product, report_confirm, product)
@doc """
User confirms product is vegan, when they have already done so.
"""
defp check_user_product(
%UserProduct{voted_vegan: true} = _usr_prduct,
{_, true} = _report_confirm,
_product
) do
"Whoops! You have already confirmed this product is vegan"
end
@doc """
User confirms product is vegan, when they have not already done so.
"""
defp check_user_product(
%UserProduct{voted_vegan: false} = usr_prduct,
{_, true} = _report_confirm,
product
) do
changeset =
Product.changeset(
product,
%{:vegan_count => product.vegan_count + 1}
)
case Api.Repo.update(changeset) do
{:ok, _} -> IO.puts("filler")
{:error, _} -> IO.puts("filler")
end
changeset =
UserProduct.changeset(
usr_prduct,
%{:voted_vegan => true}
)
case Api.Repo.update(changeset) do
{:ok, _} -> IO.puts("filler")
{:error, _} -> IO.puts("filler")
end
"Success! Confirmed is vegan"
end
@doc """
User reports product is not vegan, when they have already done so.
"""
defp check_user_product(
%UserProduct{voted_not_vegan: true} = _usr_prduct,
{true, _} = _report_confirm,
_product
),
do: "Whoops! You have already reported this product is not vegan"
@doc """
User reports product is not vegan, when they haven't already done so.
"""
defp check_user_product(
%UserProduct{voted_not_vegan: false} = usr_prduct,
{true, _} = _report_confirm,
product
) do
changeset =
UserProduct.changeset(
usr_prduct,
%{:voted_not_vegan => true}
)
case Api.Repo.update(changeset) do
{:ok, _} -> IO.puts("filler")
{:error, _} -> IO.puts("filler")
end
changeset =
Product.changeset(
product,
%{:not_vegan_count => product.not_vegan_count + 1}
)
case Api.Repo.update(changeset) do
{:ok, _} -> IO.puts("filler")
{:error, _} -> IO.puts("filler")
end
"Success! Reported not vegan"
end
def put_product_is_vegan(conn) do
product = Api.Product |> Api.Repo.get(conn.query_params["p_id"])
confirm = parse_elem(conn.body_params["confirm"])
report = parse_elem(conn.body_params["report"])
uid = conn.query_params["u_id"]
pid = conn.query_params["p_id"]
user_product =
from(usr_prduct in Api.UserProduct,
where: usr_prduct.u_id == ^uid,
where: usr_prduct.p_id == ^pid
)
|> Api.Repo.one()
user_product =
if !user_product do
UserProduct.insert_user_product(conn, %{
p_id: String.to_integer(pid),
u_id: uid,
voted_not_vegan: false,
voted_vegan: false
})
user_product =
from(usr_prduct in UserProduct,
where: usr_prduct.u_id == ^uid,
where: usr_prduct.p_id == ^pid
)
|> Api.Repo.one()
user_product
else
user_product
end
error = check_user_product(user_product, {report, confirm}, product)
product = Api.Repo.get_by(Product, id: pid)
IO.inspect(error, label: "errors")
conn
|> put_resp_content_type("application/json")
|> send_resp(
200,
Poison.encode!(%{
successs: "success",
product: product,
errors: error
})
)
end
答案 0 :(得分:1)
经验法则是您尝试严格避免在elixir中使用嵌套的if
条件语句。一般来说,它极具反习惯和代码异味。
有很多更好的方法来处理每个问题:函数子句,模式匹配,with/1
等。
解决此问题的最适用方法是坚持将条件拆分为一组具有模式匹配的函数子句。在下面几行旁边会起作用。
error = check_user_product(user_product, {report, config})
@spec check_user_product(
up :: %UserProduct{},
{report :: boolean(), config :: boolean()},
stage :: :checking_not | :checking_yes
) :: any()
defp check_user_product(up, rc, stage \\ :checking_not)
defp check_user_product(
%UserProduct{voted_not_vegan: true} = up,
{false, _} = rc,
:checking_not),
do: check_user_product(up, rc, :checking_yes)
defp check_user_product(
%UserProduct{voted_not_vegan: true} = up,
{true, _},
:checking_not),
do: "Whoops! You have already reported this product is not vegan"
defp check_user_product(
%UserProduct{} = up,
{true, _},
:checking_not),
do: changeset = [...]
defp check_user_product(
%UserProduct{voted_vegan: true} = up,
{_, true},
:checking_yes),
do: "Whoops! You have already reported this product is vegan"
defp check_user_product(%UserProduct{} = up, _, :checking_yes),
do: changeset = [...]
defp check_user_product(_, _, _),
do: "Whoops! No UserProduct"
在这里,我们对%UserProduct{}
进行模式匹配以通过投票进行模式匹配,然后立即返回或继续进行下一个检查。
想象一下,如果不确定,输入和会遵循模式匹配路径。
嵌套的条件if
是纯粹的邪恶。
通过直接与voted_vegan
和voted_not_vegan
进行模式匹配,可以完全避免第二个参数的需要,但这需要对业务领域有更多的了解,因此我将其保留为锻炼。
答案 1 :(得分:-1)
所有可能的控制流都必须返回一个字符串:
ssh::server:options:
profiles::sshd::config:
profiles::sshd::config::ssh::server:
profiles::sshd::config::options:
profiles::sshd::config::ssh::server::options: