如何在更远的关联中设置外键?

时间:2012-10-19 18:46:10

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

我有一个应用程序,其中user可以包含多个people,其中projects可以包含多个invoices {/ 1}}。

在我的invoice控制器中我有这个动作:

def create
  project = current_user.projects.find(params[:invoice][:project_id])    
  @invoice = project.invoices.build(params[:invoice])
  if @invoice.save
    flash[:success] = "Invoice created."
    redirect_to invoices_path
  else
    render :action => "new"
  end
end

问题是,只要没有project_id,它就会抛出错误。

我理解并尝试了类似的东西......

@invoice = current_user.people.projects.invoices.build(params[:invoice])

...但我收到了undefined method projects错误。

我只是想确保新的invoice会自动与正确的user相关联,并且没有人可以篡改它。

有没有办法做到这一点?

2 个答案:

答案 0 :(得分:1)

这是一种完成你想要的方法。我在我的控制台中对此进行了测试,因此它应该可行。我弄乱了人/人的多元化,但你应该得到要点。为测试目的,我给模型提供了虚拟属性。

class User < ActiveRecord::Base
  attr_accessible :name
  has_many :persons

class Person < ActiveRecord::Base
  attr_accessible :person_name, :user_id
  belongs_to :user
  has_many :projects
  has_many :people_invoices
  has_many :invoices, through: :people_invoices

class Project < ActiveRecord::Base
  attr_accessible :person_id, :project_name, :user_i
  belongs_to :person
  has_many :invoices

class PeopleInvoice < ActiveRecord::Base
  attr_accessible :invoice_id, :person_id
  belongs_to :person
  belongs_to :invoice

class Invoice < ActiveRecord::Base
  attr_accessible :invoice_amount, :person_id
  belongs_to :project
  has_many :people_invoice
  has_many :persons, through: :people_invoices

我为每个模型提供了一些虚拟属性,您可以在上面的attr_accessible字段中看到这些属性。

在我的控制台中,我尝试过:

@user = User.new(name: "User")
@person = @user.persons.create(person_name: "Employee")
@project = @person.projects.create(project_name: "foo")
@invoice = @project.invoices.create(invoice_amount: 25)
@person_invoice = @person.people_invoices.create(invoice_id:1)

通过这种关联方式,您可以致电:

@user = User.find(4)
<User id: 4, name: "User", created_at: "2012-10-19 20:18:28", updated_at: "2012-10-19 20:18:28"> 
@user.persons
=> [#<Person id: 5, user_id: 4, person_name: "Employee", created_at: "2012-10-19 20:19:00", updated_at: "2012-10-19 20:19:00">]
@person.invoices
[#<Invoice id: 1, project_id: 2, invoice_amount: 25, created_at: "2012-10-19 19:33:10", updated_at: "2012-10-19 19:33:10">]

由于这些关联,您应该能够找到与项目和人员相对应的发票,并将其追溯回特定用户。由于关系是has_many,您将获得返回给您的数组(注意最后两个控制台输出中的括号)。然后,您必须在块中循环查看或访问特定值。

希望这有帮助!

答案 1 :(得分:-1)

您应该使用through

class User < ActiveRecord::Base
    has_many :projects
    has_many :invoices, through: projects
end

class Invoice < ActiveRecord::Base
    has_many :projects
    has_one :user, through: projects
end

class Project < ActiveRecord::Base
    belongs_to :user
    belongs_to :invoice
end