在操作之前添加浅嵌套关联控制器

时间:2013-09-30 13:32:06

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-4

我使用的是浅层路由的简短形式:

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是标准方法吗?

1 个答案:

答案 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