我使用的是浅层路由的简短形式:
resources :officers, except: :new
resources :members do
resources :officers, only: :new
end
这是一个member has_many officers : officers belong_to member
关联。多年来,成员可以填补许多官员角色,这是has_many的原因。
我多年来一直处理这个问题,并决定询问一个关于处理相关has_many记录创建的首选Rails方法的问题。
在会员展示页面上,我有一个链接:
= link_to 'New Officer', new_member_officer_path(@member)
应用程序中没有new_officer_path链接,但我想让某人在网址中放入officers/new
。在官员_form partial中,如果新记录(member_id
)
id.nil?
我的第一次失败尝试:
def new
set_member
@officer = Officer.new(member_id: @member.id)
end
def set_member
if params[:member_id]
@member = Active.find(params[:member_id])
else
redirect_to members_path, alert: "Officers must be created from the Members Show view"
end
end
这个失败了,我猜是因为你无法从一个动作的被调用方法重定向。
然后我尝试了:
before_action :set_member, only: :new
def new
@officer = Officer.new(member_id: @member.id)
end
def set_member
if params[:member_id]
@member = Active.find(params[:member_id])
else
redirect_to members_path, alert: "Officers must be created from the Members Show view"
end
end
这适用于有效的members/xx/officers/new
网址,但<{1}}网址中的失败。由于没有新的路线,它进入了show动作并且尝试查找失败:id new
删除资源官员的officers/new
条件允许这种方法起作用,但我有一条不需要的路线。
第一次尝试移动东西:
only: :new
有效,但由于某种原因感觉不对。我几乎喜欢离开新路线和before_action方法。
再次,只是寻找标准方法。另外,在隐藏字段中设置外来ID是标准方法吗?
答案 0 :(得分:1)
就我个人而言,我会这样写:
def new
@member = Active.find(params[:member_id]) if params[:member_id].present?
if @member.present?
@officer = @member.officers.build
else
redirect_to members_path, alert: "Officers must be created from the Members Show view"
end
end
使用present?
避免了Ruby处理nil为false-y的方式的任何潜在问题。这不是一个大问题,但我认为最好的做法是返回布尔值而不是将Ruby对象的解释记忆为布尔值。
使用build
自动设置member_id
。我并不认为set_member
需要它自己的方法。但是,如果该方法中的逻辑变得更复杂,我可能会恢复使用set_member
。