孩子不是从父模型创建的?

时间:2012-08-08 22:55:21

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

我有一个复选框,如果选中,则允许创建名为Engineer的子资源。我正试图通过我的模型创建它,因为我可以调用after_save方法。

这是我的代码:

模型/ user.rb

class User < ActiveRecord::Base
  has_many :armies
  has_many :engineers  
end

模型/ army.rb

class Army < ActiveRecord::Base
 has_many :engineers
 attr_reader :siege
 after_save :if_siege
 private

 def if_siege
   if self.siege
    Engineer.create!( :user_id => current_user.id, :army_id => self.id )
   end
 end
end

模型/ engineer.rb

class Engineer < ActiveRecord::Base
  belongs_to :user
  belongs_to :army
end

控制器/ armies_controller.rb

def new
  @army = Army.new
end

def create
  @army = current_user.armies.build(params[:army])
    if @army.save
      redirect_to new_army_path
    else
      render :new
    end
  end
end

这给我的错误if_siege方法:

undefined local variable or method `current_user'

我该如何解决这个问题,还是有另一种方法可以做到这一点?不确定这是否应该放在控制器或模型中,但我只能把它放在模型中。

感谢。

2 个答案:

答案 0 :(得分:1)

belongs_to :user添加到Army模型

Army#if_siege中,按以下步骤更新Engineer.create!

Engineer.create!( :user_id => self.user.id, :army_id => self.id )

答案 1 :(得分:1)

首先,current_user对象不会存在于Model层的上下文中,除非您的身份验证正在执行某些操作以使其可用。这通常是非Threadsafe方法。也许对你来说这不是问题。

Current User Instantiation

话虽如此,解决这个问题的一种方法(也许不是理想的方法)是在名为Army的对象模型中创建一个attr_accessor。然后在current_user实例可用的控制器中的Army new 操作中将current_user设置为this。

# in the Army model
attr_accessor :the_user

# in the Army Controller
@army = Army.new(:the_user => current_user.id)

您还必须添加一个隐藏字段,以便在视图中存储此值,以便将其传递给创建操作。

只是一个观察,但我很确定在“if_seige”方法中 self 调用是多余的。应该已经将 self 范围限定为该方法中的Army对象。