كيفية الوصول إلى نموذج الانضمام على has_many: من خلال العلاقة
-
21-09-2019 - |
سؤال
لدي علاقة نموذجية كثيرة إلى حد ما باستخدام has_many => :through
, ، كما هو موضح أدناه.
class member
has_many member_roles
has_many roles, :through => :member_roles
end
class role
has_many member_roles
has_man members, :through => :member_roles
end
class member_role
belongs_to :member
belongs_to :role
# has following fields: member_id, role_id, scope, sport_id
end
ما أحاول القيام به هنا هو السماح للأعضاء بتعيين الأدوار. كل دور عضو له نطاق ، والذي يتم تعيينه افتراضيًا على "الكل" ولكن إذا رغبت في ذلك يمكن ضبطه على "الرياضة". إذا تم تعيين النطاق على الرياضة ، فنحن نلتقط أيضًا Sport_id ، مما يسمح لنا بتقييد التقييم على هذا الدور لرياضة معينة (أي ، يمكن فقط إدارة فرق تلك الرياضة ، بدلاً من فرق كل رياضة). تبدو بسيطة بما فيه الكفاية.
لقد قمت بإعداد بلدي update_member_roles
عمل شيء من هذا القبيل:
def update
# Assume we passing a param like: params[:member][:roles]
# as an array of hashes consisting of :role_id and if set, :sport_id
roles = (params[:member] ||= {}).delete "roles"
@member.roles = Role.find_all_by_id(roles.map{|r| r["role_id"]})
if @member.update_attributes params[:member]
flash[:notice] = "Roles successfully updated."
redirect_to member_path(@member)
else
render :action => "edit"
end
end
ما ورد أعلاه يعمل بشكل جيد بما فيه الكفاية ، فإنه يضع عضوًا مناسبًا بشكل جيد للغاية ... لكن بما أنني أعمل على نموذج الدور وليس نموذج العضو ، فأنا عالق في كيفية الوصول إلى نموذج الانضمام لتعيين: النطاق و: Sport_id.
أي مؤشرات هنا ستكون موضع تقدير كبير.
المحلول
يجب عليك استخدام member_roles
جمعية بدلا من roles
جمعية.
def update
# The role hash should contain :role_id, :scope and if set, :sport_id
roles = ((params[:member] ||= {}).delete "roles") || []
MemberRole.transaction do
# Next line will associate the :sport_id and :scope to member_roles
# EDIT: Changed the code to flush old roles.
@member.member_roles = roles.collect{|r| MemberRole.new(r)}
# Next line will save the member attributes and member_roles in one TX
if @member.update_attributes params[:member]
# some code
else
# some code
end
end
end
تأكد من إرفاق كل شيء في معاملة واحدة.
الاحتمال الآخر هو الاستخدام accepts_nested_attributes_for
تشغيل member_roles
جمعية.
نصائح أخرى
يبدو أنك يجب أن تبحث في استخدام السمات المتداخلة: