Rails:不允许:嵌套模型的id导致自动生成新实例。为什么?

时间:2016-05-21 15:01:06

标签: ruby-on-rails ruby nested-forms nested-attributes

我对嵌套模型有一个概念上的疑问,我希望我能在这个问题上明确表达。

我有3个型号, A B C A 接受 B C 的嵌套属性。在AController#new上我写@a = A.new,@ a.b.build,@ a.c.build(我将在下面分享代码)。

定义 A 的参数,我允许 B 的参数和 C 的参数。 问题:我忘了允许C&C:id

因此,每当我在我的网站上编辑 A 的实例时(例如,在' / a / 1 / edit '),它会自动创建 C 的新实例。

诊断问题非常容易(我刚发现 C ' s:ID丢失,并推断出这是问题),但我想知道为什么会发生这种情况即可。有没有人有洞察力?我的代码详情如下。

a.rb

has_many :b
has_many :c    
accepts_nested_attributes_for :b
accepts_nested_attributes_for :c

a_controlle.rb

def new
    @a = A.new
    @a = @a.b.build
    @a = @a.c.build
end

def edit
    @a = A.find(params[:id])
end

def update
    if A.find(params[:id]).update_attributes(a_params)
    #SOME CODE
end

def create
    @a = A.new(a_params)
    #SOME CODE
end

private

def a_params
    params.require[:a].permit(:a_name, b_attributes: [:id, :b_name],
    c_attributes: [:c_name]) ## SEE, I had forgotten C's :id.
end

A / new.html.erb和A / edit.html.erb都有field_for B和C.

那么,有没有人知道为什么我会访问A / [:id] /编辑它会生成C的新实例,因为我忘了允许它:id?

1 个答案:

答案 0 :(得分:1)

这是设计的。如果使用accepts_nested_attributes_for :c并发送C的属性,则如果:idC)中的c_attributes参数中没有C参数,则会创建该对象。< / p>

所以我想你有一个包含BA模型的嵌套属性的表单,每次提交表单时都会发送BCc_attributes的属性。 :id个对象。每次发送A而没有A新对象的情况都会被创建。

您可以仅为B对象或C$itemsPerPage = 10; $page = (int) $page; // get $page from route or $_GET['page'] or wherever $pageNum = (!empty($page)) ? (int) $page - 1 : 0; $start = $pageNum * $itemsPerPage; $query = "SELECT * "; $query .= "FROM records "; $query .= "WHERE published = '1' ORDER BY date DESC, time DESC "; $query .= "LIMIT $start, $itemsPerPage;"; 对象试验和创建表单,以查看是否未创建或编辑#this is your standard method definition def r_f(fn, n, vl): #these are local variables cn, rd = 0, 0 #we are saying; #in the scope of this with statement, the variable f #is equal to the file object returned by open with open(fn, 'r') as f: #for every line in the file #(because readlines returns a list of all the lines) for value in f.readlines(): #increment this variable by 1 rd += 1 #if rd is greater than n if rd > n: #break out of this loop break #if the integer representation of the line we read #is equal to v1 if int(value) == vl: #then increase this variable by 1 cn += 1 #we return this value to the function that called us return cn 个对象。

我希望这有助于您了解正在发生的事情。