با درود خدمت شما . یک مشکل بسیار ساده دارم جالبه برام که چطور بعد از اینکه من دستور متوقف کردنشو می دم بازم کار می کنه.
به عنوان مثال شما فانکشن زیر رو ببنید
def create_learn_headlines(conn, %{"title" => title, "status" => status} = allreq) do
if 2 === 2 do
activity_learn_error_handeller(conn, {:error}, :error)
halt(conn)
IO.puts "test1"
end
IO.puts "test2"
end
با اینکه من بهش گفتم متوقف بشه الان هم test1 و هم test2 رو داره چاپ می کنه یکمی نسبت به if جدیدا حساس شدم . نکنه موارد دیگه هم برام باگ ایجاد کنه
احساس می کنم این مورد فقط داره کانکشن یعنی conn رو غیر فعال می کنه و دیگه کاری با فانکشن نداره
لازم به ذکر هست من تابع خودمو با case نوشتم یعنی مشکلی در اون رابطه نیست ولی if بود تعداد خط هاش کمتر بود و خوانایی بیشتر می شد
به عنوان مثال نسخه ری فکتور شده
test = case Ecto.UUID.cast(cms_learn_category_id) do
:error ->
activity_learn_error_handeller(conn, {:error}, :error)
_ ->
headline = LearnQuery.create_learn_head_lines(allreq)
activity_learn_error_handeller(conn, headline, "created")
end
test
بیشتر مشکلم با اینه که چرا نمی تونم تابع رو متوقف کنم تا اینکه خود استفاده مناسب از کد برای این مشکل بنده در schema اومدم یک ولیدیشن سفارسی برای برای changeset درست کردم. تشکر
در کل در الیکسر چیزی با عنوان early return وجود نداره.
در مورد کدی که شر کردی هم من متوجه نمیشم کدوم قسمت کد قراره فانکشنو متوقف کنه، halt هم که از اجرای پلاگ های بعد از halt جلوگیری میکنه. چیز عجیبی اون بالا نمیبینم اگر بیشتر توضیح بدی ممنون میشم.
درود توماج جان در ادامه توضیحم و همینطور به این مورد اشاره کردم که halt الان جلوگیری کننده از پلاگ هست نه فانکشن و نیاز به این داشتم که چیزی رو بهم پیشنهاد داده بشه برای متوقف کردن فانکشن. مثلا یک چیزی به نام exit در php . البته من نیازمو همانطور که قبلا گفتم در راه دیگه ای حل کردم ولی برام سوال شده چرا اینطور هست و راه حل چیست ؟
درست می فرمایید . مثلا در کنترلر در قسمت گرافیکی می شه با ریدایرکت حلش کرد راه هاش زیاده ولی همانطور شما فرمودید راه مستقیم نیست البته من مشکلمو با ساخت یک ولیدیشن در changeset حل کردم
به این صورت که کلا ارور برگردونه و مشکلم حل بشه
defp validate_field_relational(changeset, field) do
field_concerned = get_field(changeset, field)
case Ecto.UUID.cast(field_concerned) do
:error ->
add_error(changeset, field, "relational field is invalid")
_ ->
changeset
end
end
متاسفانه UUID استفاده شده رو فونیکس برای ID یک جدول تشخیص می ده درست هست یا خیر یعنی ولیده ولی اگر همین مورد برای یک فیلد رلیشن شده ارسال بشه و ولید نباشه ارور ۵۰۰ می ده
قبلا هم اینجا قرار دادم مشکلمو راه پیدا کردم براش خیلی زیاد ولی می خواستم خودشون حلش کنند اینجا بهم یک پاسخ سریع و بی ارزش داد و ازش عبور کرد
حتی انقدر وقت نزاشت اون پست لینک دادم رو بخونه خاک بر سرش
به روز رسانی
البته یک راه دیگه ای هم به یادم اومد الان می تونم در شرط یک اتم :error بر گردونم اینم خودش باعث می شد کارم راه بیفته
حتی راه غیر مستقیمی هم وجود نداره، فانکشن ها باید تا پایان کارشونو ادامه بدن و ما باید با طراحی مناسب عملیات درست رو بر اساس فراوانی value هایی که در فانکشن وجود دارند انجام بدیم، هدف الیکسر هم تا جایی که میشه جلوگیری از طراحی بده. راستش اصلا نمیدونم چرا به early return نیاز هست، واقعا لازم نیست.
Redirect و render هم باید آخرین اتفاقی باشه که توی اکشن رخ میده.
به صورت عادی همیشه module های خارج از کنترولر فقط با منطق اصلی برنامه باید کار داشته باشن و حالت درست یا نادرست به صورت error برگردونن
کنترولر و پلاگ ها فقط باید با conn کار کنن و نسبت به خروجی module های خارجی تصمیم بگیرن که conn ادامه داشته باشه یا نه