更新has_one关联模型

时间:2014-01-21 08:45:20

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

我有两种模式:

Student > belongs_to Locker
Locker  > has_one    Student

通过这种关联,我必须去更衣室并给它分配一个学生,或者如果我要转变协会,我可以去学生并给他一个储物柜。

这是有效的,我理解。 但是,目前我的设置如上所述。

现在,当然,有人想到直接为我正在创作的学生(新学生)分配一个储物柜会非常酷。

所以在这种情况下,我确实有更衣室,但学生现在不在场,而且当它被创建时,也应该创建从储物柜到这个学生的关联。 因此,实际上会创建一个ID为XXX的新学生,但同时这个ID也应该转到一个储物柜及其student_id属性。

我正在敲打我的脑袋如何处理这个,因为我发现这些选项并没有真正完成这项工作(我使用的是simple_form btw): - 使用关联 - accepts_nested_attributes

我唯一能看到它以某种方式将所选储物柜ID的假身份证(attr_accesor)发送给学生模型,创建学生,记下其身份证,找到储物柜,用这个新身份更新储物柜。

但这感觉很奇怪和错误。

有人能指出我正确的方向吗?

2 个答案:

答案 0 :(得分:1)

如果您的关联配置正确,那么您的学生表中有:locker_id,因此您只需在新学生表上选择一个复选框即可。

<% form_for @student do |form| %>
  <%= form.input :name %> # etc...
  <%= form.collection_select(:locker_id, @unassigned_lockers, :id, :name) %>
  <%= form.submit %>
<% end %>

这是一个非常简单和标准的案例,除非你没有告诉我们。

注意,我已经抛出一个@unassigned_lockers对象而不是Locker.all,因为你想在这里有一些逻辑,只显示下拉列表中未分配的储物柜,我认为。

由于您没有按照最初描述的方式设置关系,因此无法在不手动处理的情况下向学生提交:locker_id。作为一个快速的建议:

<% form_for @student do |form| %>
  <%= form.input :name %> # etc...
  <%= collection_select_tag(:locker_id, @unassigned_lockers, :id, :name) %>
  <%= form.submit %>
<% end %>

选择标记现在将在参数中单独显示,您需要更改create方法以找到锁定并更新其学生ID:

def create
  @student = Student.new(params[:student])
  if @student.save
    Locker.find(params[:locker_id]).update_attribute(:student, @student)
  end
end

当然,这需要一些错误捕捉和改进,但应该让你开始。

答案 1 :(得分:0)

没试过你的解决方案,但是你立即提醒了after_create,after_update:

在学生中:

after_create :update_locker
after_update :update_locker

 private

  def update_locker
    Locker.update(self.locker_id, :student_id => self.id)
  end

我现在确实有更衣柜验证的问题,当然,因为只有一个学生可以拥有储物柜,而不是更多。目前如果我选择一个已经使用过的储物柜,并通过我的解决方案更新它,我获得成功更新学生留言,但储物柜未更新。