چطور در بین query در الکسیر شرط قرار بدهیم ؟

با درود خدمت شما . لطفا به این کد توجه کنید

post = Repo.all from p in PostCategory,
           join: c in assoc(p, :cms_post),
					 where: p.id == ^category_id,
					 if group_acl != "admin" do
						 where: p.group_acl == ^group_acl,
  					     where: c.group_acl == ^group_acl,
					 end
					 order_by: p.inserted_at,
					 limit: 10,
           preload: [cms_post: c]

برای اینکه دوباره بخش های تکراری رو ننویسم سعی کردم یک شرط بزارم ولی خوب مشکل سینتکزس داره

لینک هایی مثل این رو هم دیدم
https://hexdocs.pm/ecto/Ecto.Query.html#select_merge/3

ولی همشون انگار می گند باید دوبار یک قطعه کد رو بنویسم نه اینکه بتونم یک شرط ساده رو بیام استفاده کنم

دو سال

۱. چطور شرط در بین کوآری استفاده کنیم ؟
۲. آیا این راه درست هست یا خیر؟

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

احتمال می دم بخاطر مشکل زبان باشه که متوجه نشدم

لازم به ذکر هست در این کد من فقط فقط نیاز دارم دو خط زیر در شرط باشند

where: p.group_acl == ^group_acl,
where: c.group_acl == ^group_acl,

چون برخلاف بقیه این دو خط تکرار نمی شند

تا جائی که میتونی از پترن مچینگ با function کار کن

def fetch_post("admin") do
  Repo.all from p in PostCategory,
           join: c in assoc(p, :cms_post),
           where: p.id == ^category_id,
           order_by: p.inserted_at,
           limit: 10,
           preload: [cms_post: c]
end

def fetch_post(_) do
  Repo.all from p in PostCategory,
           join: c in assoc(p, :cms_post),
           where: p.id == ^category_id,
           where: p.group_acl == ^group_acl,
           where: c.group_acl == ^group_acl,
           order_by: p.inserted_at,
           limit: 10,
           preload: [cms_post: c]
end
2 پسندیده

درود سام عزیز . بله کاملا صحیح می فرمایید بیشتر برای اینکه زیاد کپی پست نکنم برای دو خط این کارو می خواستم دنبال کنم تا پترن . اول هم پترن اتفاقا البته تقریبا مثل شما زدم ولی خوب احساس کردم دارم کپی پست می کنم زیاد

البته الان راه شرط قرار دادن رو یکی تو اون پست گفت که بازم زیاد از نظرم زیبا نیومد انگار دوباره داری به اصل کو آری دستور می دی فکر کنم پترنی که شما می فرمایید خیلی بهتر باشه

1 پسندیده

DRY اصل بدی نیست ولی یک وقتا کد غیر قابل فهم میکنه من کد تکراری خوانا رو ترجیح میدم به dry که طول میکشه درکش کرد

1 پسندیده

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

1 پسندیده

منظور شما رو متوجه شدم، اما همونطور که خودت بهتر میدونی در الیکسر همه چیز پترن مچینگه🧐

2 پسندیده

آیا میدونستید در مقابل مخفف DRY که کاملش میشه Don’t Repeat Yourself, مخفف دیگه ای هم هست با عنوان WET که شکل کامل اون هست Write Everything Twice :hugs:

https://www.codementor.io/joshuaaroke/dry-code-vs-wet-code-89xjwv11w

2 پسندیده

درود خدمت دو بزرگوار که بر گردن بنده حق معلمی دارند هم توماج عزیز هم @samdvr عزیز .

یک سوال کوچیک می خواستم از خدمت شما دو عزیز بپرسم.

ما خیلی خیلی ساده می تونیم در الکسیر در همه چیز از پترن استفاده کنیم و شکل خاص و سفارشی شده خودمان را در بیارویم .

به صورت مثال من می خواستم یک استراکت رو در یک لیست در بیارم براش یک ماژول enum داشت و یکی هم map حالا سوال اساسی شما از یک ماژول از قبل تعریف شده الکسیر استفاده می کنید یا ترجی می دید پترن درست کنید ؟

یکم بیشتر توضیح میدی؟

لطفا تصویر بالا رو ببنید هم می شه با

Map.get/3
Enum.map/2

گرفت هم می شه با پترن گرفت مثلا

[%TrangellCmsService.Cms.Db.Post{} = o | _c ] = list_params

or

def get_title([%TrangellCmsService.Cms.Db.Post{title: title}|_]),
  do: title

شما کدوم رو می پسندی پترن یا ماژول پیشفرض الکسیر ؟ چرا ؟

همه موارد بالا در الیکسر به صورت پترن مچینگ انجام میشه، من ترجیح میدم روش خواناتر و ساده تر رو استفاده کنم. فانکشن های موجود در الیکسر قراره که خیلی خوب از پس کارشون بر بیان پس من تا وقتی عکسش اثبات بشه از فانکشن های موجود استفاده میکنم + این که مدیریت ارور ها که در فانکشن های از پیش تعریف شده انجام شده و زحمت کار کمتر میشه

1 پسندیده

اگر پاسخ من مناسب پرسش شما نبود معنیش اینه که نیاز به توضیح بیشتر دارم

1 پسندیده

توماج جان کاملا جوابی که بنده می خواستم رو داید دنبال دلایل شما برای این کار بودم . باز هم نظرات رو در این زمینه جمع کنم می رم برای تصمیم آخر در

در این پست هم پرسیدم

ممنونم از وقتی که قرار دادید تشکر

1 پسندیده

پاسخ دوستان رو در پست فروم الیکسر خوندم اما من بازم نظرم همونه! البته سوالی که اونجا پرسیده شده شباهت زیادی به سوالی که اینجا پرسیدی نداره :thinking:
گاهی ما فقط قصد داریم مقدار یک کلید در ریشه ساختار رو استخراج کنیم مثل موردی که شما مثال زدین، واقعا پیچیدگی خاصی نداره و Map.get/3 به راحتی و بدون دردسر این کارو انجام میده، اما گاهی هم باید با ساختار پیچیده تری کار کنیم و یا داده های بیشتری رو استخراج کنیم که احتمالا destructuring با استفاده از پترن های سفارشی معنی بیشتری پیدا میکنه.
انتخاب باید بر اساس پیچیدگی ساختار و نیاز باشه اما راه حل اول باید همیشه ساده ترین راه باشه چون اصلا چیزی با عنوان کدنویسی خوب وجود نداره، recator خوب داریم که اگر با کدنویسی ساده و خوانا شروع کرده باشیم بهتر هم میشه :slightly_smiling_face:

1 پسندیده

درود توماج جان بخوام کامل تر خدمت شما اطلاعات بدم

این خروجی کواری من هست

اگر نگاه بکنید بهش می بنید در آخر این خروجی برای بنده اطلاعاتی می زاره که اطلاعات مجموعه من هست
و داخل هر استراکت %TrangellCmsService.Cms.Db.Post با اسم مذکور اطلاعات پست های من هست . به صورت خلاصه تمام پست های یک مجموعه رو می یاره . حالا شما بودید چطور از این استخراج می کردید؟

به عنوان مثال من نتونستم اینطوری بگیرمش

Map.get(p, %TrangellCmsService.Cms.Db.Post{}, :title)

فکر کنید کل خروجی که گیست کردم در یک متغییری به نام post هست حالا می خوام چاپش کنم به صورت کاستوم

def load_posts_by_category_alias(category_alias, group_acl) do
		post = fetch_posts_by_category_alias(category_alias, group_acl)


		for p <- post do
			# Enum.map(p, &(Map.get(&1,:title)))
			Map.get(p, %TrangellCmsService.Cms.Db.Post{}, :title)
		end
	end
1 پسندیده

به عنوان مثال من نتونستم اینطوری بگیرمش

میشه اینو توضیح بدی؟

1 پسندیده

درود خدمت توماج عزیز .
یعنی اینکه متاسفانه من می خواستم به وسیله ماژول های Enum, Map بگیرم.

در کل من چنین خروجی می خوام بدم

%{
			title: p.title,
			status: p.status,
			post_type: p.post_type,
			download_ext_link: p.download_ext_link,
			price: p.price,
			pic_x1_link: p.pic_x1_link,
			pic_x2_link: p.pic_x2_link,
			pic_x3_link: p.pic_x3_link,
			group_acl: p.group_acl,
			description: p.description,
			changelog: p.changelog,
			changelog_category: p.changelog_category,
			plugin: p.plugin,
			plugin_category: p.plugin_category,
			discourse: p.discourse,
			discourse_link: p.discourse_link,
			screen_shot: p.screen_shot,
			screen_shot_category: p.screen_shot_category,
			learn: p.learn,
			learn_category: p.learn_category,
			seo_tag: p.seo_tag,
			seo_alias_link: p.seo_alias_link,
			seo_words: p.seo_words,
			seo_description: p.seo_description,
			seo_language: p.seo_language,
			seo_language_link: p.seo_language_link,

			category_title: c.title,
			category_status: c.status,
			category_language: c.language,
			category_group_acl: c.group_acl,
			category_seo_alias_link: c.seo_alias_link,
			category_pic_x1_link: c.pic_x1_link,
			category_pic_x2_link: c.pic_x2_link,
			category_pic_x3_link: c.pic_x3_link,
		}

یعنی هر پست با اطلاعات مجموعه اش.

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

لینک :

ویرایش شده به وسیله خودم :

def load_posts_by_category_alias(category_alias, group_acl) do
		category = fetch_posts_by_category_alias(category_alias, group_acl)
		|> Enum.find(& &1.seo_alias_link == "#{category_alias}") # here you have list element


		post = category
		|> Map.fetch!(:cms_post) # here you are fetching sub-list from element
		# |> Enum.map(& &1.title) # finally here you are getting title for all elements

		for %TrangellCmsService.Cms.Db.Post{} = p <- post do
			%{post_id: p.id, category_title: category.title}
		end
	end

چون طرف فقط تایتل می گرفت من می خواستم همه چیز بگیرم برای اینکه تکرار نشه اینطوری زدم . نمی دونم چرا اینطور کد زدن زیاد منو راضی نمی کنه فکر می کنم یکجا اشتباه کردم شما اینطوری فکر نمی کنید ؟:thinking: :disappointed_relieved:

فکر میکنم باید سوال خیلی ساده تر و دقیقتر پرسیده میشد، اگر دقیقا توضیح بدی که به چی نیاز داری بلاخره میشه از یک جایی شروع کرد اما چیزی که من از اول گرفتم این بود که شما فقط فیلد title و نیاز داری.
پرسش های کلی خوبه اما ممکنه مارو از سوال اصلی دور کنه، گاهی هم دادن راه حل در کنار پرسش اونم وقتی خود سوال دقیق نیست بیشتر گیج کنندست. من گاهی یک سوالی میپرسم بدون اینکه بگم هدف اصلی چیه بعد دو سه تا راه حل هم به طرف میدم که خود به خود تبدیل به بخشی از سوال میشند و میگم؛ شما کدو رو انتخاب میکنید؟ طرف گیج میشه و فرار میکنه و من از دستش خلاص میشم😹

امیدوارم حسابی رفته باشم روی اعصابت با این پاسخ :wink:

1 پسندیده

اصلاح شد :point_up_2: