جلوگیری از ادامه فعالیت فانکشن در کنترلر الکسیر

با درود خدمت شما . یک مشکل بسیار ساده دارم جالبه برام که چطور بعد از اینکه من دستور متوقف کردنشو می دم بازم کار می کنه.

به عنوان مثال شما فانکشن زیر رو ببنید

   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 درست کردم. تشکر

1 پسندیده

در کل در الیکسر چیزی با عنوان early return وجود نداره.
در مورد کدی که شر کردی هم من متوجه نمیشم کدوم قسمت کد قراره فانکشنو متوقف کنه، halt هم که از اجرای پلاگ های بعد از halt جلوگیری میکنه. چیز عجیبی اون بالا نمیبینم اگر بیشتر توضیح بدی ممنون میشم.

1 پسندیده

درود توماج جان در ادامه توضیحم و همینطور به این مورد اشاره کردم که halt الان جلوگیری کننده از پلاگ هست نه فانکشن و نیاز به این داشتم که چیزی رو بهم پیشنهاد داده بشه برای متوقف کردن فانکشن. مثلا یک چیزی به نام exit در php . البته من نیازمو همانطور که قبلا گفتم در راه دیگه ای حل کردم ولی برام سوال شده چرا اینطور هست و راه حل چیست ؟

1 پسندیده

احتمالا درست نخوندم :face_with_thermometer:
همونطور که عرض کردم در الیکسر early return وجود نداره، میتونی با مسیر شرطی و options حلش کنی

1 پسندیده

درست می فرمایید . مثلا در کنترلر در قسمت گرافیکی می شه با ریدایرکت حلش کرد راه هاش زیاده ولی همانطور شما فرمودید راه مستقیم نیست البته من مشکلمو با ساخت یک ولیدیشن در 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 یک جدول تشخیص می ده درست هست یا خیر یعنی ولیده ولی اگر همین مورد برای یک فیلد رلیشن شده ارسال بشه و ولید نباشه ارور ۵۰۰ می ده

قبلا هم اینجا قرار دادم مشکلمو راه پیدا کردم براش خیلی زیاد ولی می خواستم خودشون حلش کنند اینجا بهم یک پاسخ سریع و بی ارزش داد و ازش عبور کرد

حتی انقدر وقت نزاشت اون پست لینک دادم رو بخونه خاک بر سرش :smile:

به روز رسانی

البته یک راه دیگه ای هم به یادم اومد الان می تونم در شرط یک اتم :error بر گردونم اینم خودش باعث می شد کارم راه بیفته

1 پسندیده

قسمت گرافیکی یعنی چی؟

حتی راه غیر مستقیمی هم وجود نداره، فانکشن ها باید تا پایان کارشونو ادامه بدن و ما باید با طراحی مناسب عملیات درست رو بر اساس فراوانی value هایی که در فانکشن وجود دارند انجام بدیم، هدف الیکسر هم تا جایی که میشه جلوگیری از طراحی بده. راستش اصلا نمیدونم چرا به early return نیاز هست، واقعا لازم نیست.
Redirect و render هم باید آخرین اتفاقی باشه که توی اکشن رخ میده.

1 پسندیده

بله الان متوجه شدم راه های زیادی وجود داره و نیازی به این کار نیست می شه از راهای دیگه این مورد رو هندل کرد

منظورم از بخش گرافیکی همون بخش render html هست در کنترلر فونیکس البته اگر html باشه. چون فکر نمی کنم این کار توی json وب سرویس کاربردی داشته باشه

1 پسندیده

action

1 پسندیده

به صورت عادی همیشه module های خارج از کنترولر فقط با منطق اصلی برنامه باید کار داشته باشن و حالت درست یا نادرست به صورت error برگردونن
کنترولر و پلاگ ها فقط باید با conn کار کنن و نسبت به خروجی module های خارجی تصمیم بگیرن که conn ادامه داشته باشه یا نه

1 پسندیده