2014-01-21 81 views
0

我有两个型号:更新HAS_ONE相关模型

Student > belongs_to Locker 
Locker > has_one Student 

与此相关联,我不得不去更衣室,并为其分配一个学生,或者如果我会转身的关联,我可以去的学生,给他分配一个储物柜。

这是什么工作,我理解。 但是,目前我有像上面描述的设置。

当然,现在有了一个想法,那就是直接为我正在创建的学生(新生)直接分配一个储物柜将会非常酷。

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

我敲我的脑袋如何处理这一点,因为我想通了这些选项并不真正做的工作(我使用simple_form BTW): - 利用协会 - accepts_nested_attributes

唯一的办法我看到它以某种方式发送虚假身份证(attr_accesor)选定的锁柜ID到学生模型,创建学生,写下它的ID,找到更衣室,更新储物柜与这个新的ID。

但它感觉很奇怪和错误。

难道有人指着我正确的方向吗?

回答

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 %> 

选择标签现在将在PARAMS分开来实现它,你将需要改变你的create方法找到更衣室和更新其学生证:

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

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

+0

这正是我采取的方式 - 但我结束了太多的IF和案例。看起来很复杂,我觉得没有效果。 在新文章中额外评论。 –

+0

梅,不能编辑评论了。 我们不仅在谈论创建一个新学生/附加现有的储物柜。但也更新学生/储物柜。由于需要考虑一些组合,这会带来更多的复杂性。它变得越来越复杂。我正在调查nested_attributes,但得出的结论是,我真的很想达到目标。 –

+0

这个答案中的代码也可以很好地编辑学生...只需按照标准更新程序,并在学生保存后包含更衣室逻辑。如果'params [:locker_id]'不等于学生当前的储物柜ID,请确保您取消分配他们当前的储物柜。 – Matt

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 

我有带锁的验证问题了,当然,由于只有一个学生可以有更衣室,而不是更多。目前,如果我选择一个已经使用过的储物柜,并通过我的解决方案进行更新,我可以在视图中成功更新学生信息,但储物柜不会更新。