2

我正在使用一种简短的浅路由:

resources :officers, except: :new

resources :members do
  resources :officers, only: :new
end

这是一个member has_many officers : officers belong_to member协会。多年来,成员可以担任许多官员角色,这就是 has_many 的原因。

多年来我一直在处理这个问题,并决定就 Rails 处理创建关联 has_many 记录的首选方式提出问题。

在会员展示页面上,我有一个链接:

= link_to 'New Officer', new_member_officer_path(@member)

应用程序中没有 new_officer_path 链接,但我想诱捕有人在officers/newurl 中输入。在Offices _form 部分中,我将隐藏字段设置member_id为@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/newurl 调用中有效,但在 on url中失败。officers/new由于没有新的路线,它去了 show action 并失败尝试找到 :id new

取消only: :new对资源官员的条件允许这种方法起作用,但我有一条不需要的路线。

在我的第一次尝试中移动东西:

def new
  set_member
  if @member
    @officer = Officer.new(member_id: @member.id)
  else
    redirect_to members_path, alert: "Officers must be created from the Members Show view"   
  end
end

def set_member
  if params[:member_id]        
    @member = Active.find(params[:member_id])
  end
end

有效,但由于某种原因感觉不对。我几乎喜欢离开新路线和 before_action 方法。

同样,只是寻找标准方法。另外,在隐藏字段中设置外国 ID 是标准方法吗?

4

1 回答 1

2

我个人会这样写:

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

usingpresent?避免了 Ruby 将 nil 处理为 false-y 的方式的任何潜在问题。不是一个大问题,但我认为最好的做法是返回布尔值,而不是将 Ruby 对对象的解释记住为布尔值。

使用build自动设置member_id. 而且我觉得set_member不需要它自己的方法。但是,如果该方法中的逻辑变得更复杂,我可能会恢复使用set_member.

于 2013-09-30T13:44:51.343 回答