دوستان برای این که اعداد فارسی هنگام ثبت فرمی (که فیلد عددی داره) توسط ریلز پشتیبانی بشه، دنبال یه راهکار کلی میگردم. من هم با یه متد به صورت before_validation در مدل و هم با یه متد توی کنترل و با جایگزینی اعداد فارسی با انگلیسی تونستم این کار رو انجام بدم، ولی دنبال یه راه حل system-wide برای پشتیبانی اعداد فارسی هستم.
مشکل نمایش نیست. موقع اجرای ولیدیشنهای عددی، دادهی عددیای که params تو خودش داره باید با کاراکترهای انگلیسی باشه تا هنگام ثبت فرم، ارور «عدد نیست» نده. یعنی params دریافتی بجای این حالت
{..., "product"=>{"price"=>"۱۲۳۴"},...}
باید این حالت رو داشته باشیم:
{..., "product"=>{"price"=>"1234"},...}
حالا میشه کاری کرد که مثلا قبل از اینکه هش params ساخته بشه، اعداد فارسی رو با معادل انگلیسیش جایگزین کرد؟ یا حتی راه دیگهای هست؟ (مثلا شناسوندن کاراکترهای اعداد فارسی به عنوان «عدد» به ریلز یا …)
مشکل من متد تبدیل دوتا به هم نیست. مسئله اینه که کجا این متد اجرا بشه تا همهی اعداد دریافتی فارسی (در کل اپ) به انگلیسی تبدیل بشن. که مثل نمونه بالا توی params دریافتی اعداد فارسی اصلا وجود نداشته باشن. یعنی میخوام این تبدیل توی یه سطح پایینتری قبل از این که به کنترلر برسه انجام شده باشه.
@arvinje براي اينكه اين كارو توي كنترلر انجام بدي بايد كد رو توي ApplicationController.rb بنويسي چون همه كنترلرها وارث اين كنترلر هستن، در ضمن ميتوني با رعايت كنوانسيون هاي ريلز (Convention-over-Configuration) خودت يه ماژل درست كني و تو هرجا كه خواستي include كني.
اگر من جاي شما باشم براي model ها يه ماژل مينويسم و ماژل رو توي يه پوشه به اسم همون ماژل قرار ميدم. ميشه پارامترها رو به شكل يه آرايه به متد پاس داد و خود متد رو به صورت سمبل (symbol) به before_save
این کارو به این سادگی نمیشه انجام داد. اول اینکه اگه صفت عددی باشه، دادهی رشتهای اصلا ذخیره نمیشه که حتی بشه به صورت before_validation رقمها رو جایگزین کرد. دوم هم اینکه callbackها نمیتونن پارامتر بگیرن.
تنها راه کلیای که من به نظرم میرسه اینه که تمام صفتهای موجود توی هش params توی کنترلر از نظر عددی بودن بررسی بشن و اگه عددی بودن با ارقام انگلیسی جایگزین بشن که توی این حالت هم چون ممکنه هش شامل هشهای تودرتو و آرایه هم باشه پرفورمنس خوبی نخواهد داشت.
البته میشه یه سری متد جایگزین new و update توی مدل ساخت که با گرفتن params قبل از فراخوانی new و update واقعی تبدیل رو انجام بدن. با این حال باز هم کل هش باید پیمایش بشه.
@arvinje چرا روی before_save توی model کار نمی کنی؟ فکر می کنم بهتر باشه مگر اینکه یک دلیل خیلی خوب وجود داشته باشه. من این تست رو انجام دادم. یه نمونه برات پست می کنم
در هر صورت اگه صفت (توی جدول)از نوع integer (یا float) تعریف شده باشه، دادهی رشتهای اصلا نمیتونه بهش نسبت دادهبشه. همچنین درنظر داشته باش که میخوایم صفت بتونه از هر نوع ولیدیشن عددی هم پشتیبانی کنه.
@arvinje مم… جالب شد! البته من نمیدونم که آیا صفت یعنی سمبل یا خیر؟ من داشتم به همین داستان ولیدیشن فکر می کردم، به هر حال باید بتونیم این کارو انجام بدیم، سعی می کنم یه نگاهی به locale و internationalization بندازم، اما به نظرم این کار چندان نشدنی نیست. اگر جامعه ریلز راه حل آماده ای نداشت بازم یه کاریش می کنیم.
همه اعداد طبیعتا به حالت integer یا float ذخیره میشن که انگلیسی و فارسی نداره. برای خروجی فارسی هم میشه یه متد مثل t نوشت که تبدیل رو انجام بده (یا حتی t رو تغییر بدیم)
مشکل اصلی هنگام سابمیت کردن فرم هاست. مسئله اینه که کاربر میتونه توی فیلد اون صفت* توی view رقم فارسی وارد کنه که این حالت پیش میاد
که در این صورت activerecord مقدار اون صفت رو صفر درنظر میگیره چون عدد فارسی رو پشتیبانی نمیکنه. یعنی حتی اون عدد توی صفت عددی ذخیره نمیشه که بشه تغییرش داد. پس باید قبل از انتساب صفت تغییر ارقام فارسی به انگلیسی انجام بشه.