你如何在控制器中给它所属的ID?

时间:2011-07-17 17:47:38

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

如何在控制器中为我的产品提供user_id,Location_id和product_dates_id?

class Product < ActiveRecord::Base
  belongs_to :user
  belongs_to :location
  belongs_to :product_date
end

我的控制器:

def new
    @location = Location.new
    @product = Product.new
    product_date = @location.product_dates.build
    product_date.products.build
end

def create
    @location = Location.new(params[:location])
end

我的表:

create_table :products do |t|
      t.integer :user_id
      t.integer :location_id
      t.integer :product_date_id
end

谢谢。

2 个答案:

答案 0 :(得分:2)

@location = Location.create(params[:location])
@location.products.each{ |p| p.update_attribute :user_id, current_user.id }
@location.product_dates.map(&:products).flatten.each{ |p| p.update_attribute :user_id, current_user.id }

或者更好地将:user_id的隐藏字段添加到每个产品和product_date

答案 1 :(得分:1)

回答你的问题

def new
    #First create the new product object assuming you have a current_user available. If not you will need to make a current_)user available.
    @product = current_user.build_product
    #Now build a new location for the product
    location = @product.build_location # You don't need location to be an instance variable.
    #when you reference @location in your form you should now be using fields_for :locations instead.
    #build a new product_date object for the location_product_dates array
    product_date = @location.product_dates.build
    #Now add that product date object to the product
    product.product_date = product_date
end

将accepts_nested_attributes声明添加到相关模型并在相关产品表单中使用fields_for声明,这样您的创建和更新操作不需要对它们进行任何更改,因为表单中的fields_for声明将安排相关对象具有当回发到创建和更新操作时,它们的数据嵌套在产品哈希中。

将所有正确模型和所有内容的accepts_nested_attributes_for声明结合起来,将自动更新/创建

那回答你的问题。新操作会构建所有记录并为您设置所有关联,但在我看来,您并不真正需要与产品关联的product_date,因为它已经与产品关联的位置相关联,并且作为location可以包含许多产品(基于您原来的新操作的假设),您很难找出多个位置记录中的product_date及其关联的product_date记录应直接添加到产品中。

我猜你的关联有点不对。

您还应该考虑将新操作重构为产品模型上的类方法,以使您能够执行类似

的操作
@product = Product.new_with_associations(current_user)

def self.new_with_associations需要与我为新操作提供的代码完全相同,但是您需要将current_user作为参数散列传递给会话散列(current_user将在哪里)非常好的理由是模型无法使用。

将它放在产品的类方法中不仅可以清理控制器代码,还可以使代码重复使用,并且可以更轻松地从控制台和测试套件中进行测试