rails - 已选择关联参数,但参数 "changing" 仍然存在
rails - association params selected, but params "changing" on persist
我真的不知道如何描述这个问题,而且我以前从未遇到过这样的问题。我正在尝试建立一个 "has_many :through" 协会来处理对群组的成员资格请求。其他操作(销毁、更新)似乎工作正常。每当我在我的控制器中启动创建操作时,该对象都会显示它正在传递正确的参数并创建关联。但是,它只与 ID 为“1”的组建立关联。我不知道如何清楚地解释或解决这个问题。我会 post 我的日志和代码如下。
澄清我的问题:为什么数据 "changing" 持久化到数据库(创建时)?
Cliqs = 组
日志:
Started POST "/cliqs/2/cliq_requests" for ::1 at 2016-03-31 20:35:32 -0500
Processing by CliqRequestsController#create as HTML
Parameters: {"authenticity_token"=>"uaVHFgB7digMywl2a/n2GKMtwi691WA/dw2F2mzdkSCK69C46TZICiSp90xldj3hosFwSOPEi3fSOvOSkIVMjA==", "cliq_id"=>"2"}
Cliq Load (0.0ms) SELECT `cliqs`.* FROM `cliqs` WHERE (2) LIMIT 1
User Load (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
(0.0ms) BEGIN
SQL (1.0ms) INSERT INTO `cliq_requests` (`cliq_id`, `user_id`, `created_at`, `updated_at`) VALUES (1, 1, '2016-04-01 01:35:32', '2016-04-01 01:35:32')
(198.0ms) COMMIT
Redirected to http://localhost:3000/cliqs
Completed 302 Found in 237ms (ActiveRecord: 199.0ms)
控制器操作:
def create
@cliq = Cliq.find_by(params[:cliq_id])
@cliq_request = current_user.cliq_requests.new(cliq: @cliq)
if @cliq_request.save
redirect_to cliqs_path
else
redirect_to current_user
end
end
其他操作(以防万一):
def update
@cliq = Cliq.find_by(params[:cliq_id])
@cliq_request = CliqRequest.find(params[:id])
@cliq_request.accept
end
def destroy
@cliq = Cliq.find_by(params[:cliq_id])
@cliq_request = CliqRequest.find(params[:id])
@cliq_request.destroy
if @cliq_request.destroy
redirect_to cliqs_path
else
redirect_to current_user
end
end
还有模特们:
class User < ActiveRecord::Base
has_one :owned_cliq, foreign_key: 'owner_id', class_name: 'Cliq', dependent: :destroy
has_many :cliq_memberships, dependent: :destroy
has_many :cliqs, through: :cliq_memberships
has_many :cliq_requests, dependent: :destroy
end
class Cliq < ActiveRecord::Base
belongs_to :owner, class_name: 'User'
has_many :cliq_memberships, dependent: :destroy
has_many :members, through: :cliq_memberships, source: :user
has_many :cliq_requests, dependent: :destroy
has_many :pending_members, through: :cliq_requests, source: :user, foreign_key: 'user_id'
end
class CliqRequest < ActiveRecord::Base
#from
belongs_to :user
#to
belongs_to :cliq
def accept
cliq.members << cliq.pending_members.find(user_id)
destroy
end
end
最后是我的观点:
<h1><%= @cliq.name %></h1>
<%= link_to 'Request to join Cliq', cliq_cliq_requests_path(@cliq, @cliq_request), :method => :post %>
<% @cliq_members.each do |cliq_member| %>
<ul><%= link_to cliq_member.username, user_path(cliq_member) %></ul>
<% end %>
<h3>Cliq Requests:</h3>
<ul>
<% @cliq.pending_members.each do |pending_member| %>
<%= link_to pending_member.username, user_path(pending_member) %>
<% end %>
<% @cliq.cliq_requests.each do |cliq_request| %>
<%= link_to "Accept", cliq_cliq_request_path(@cliq, cliq_request), :method => :put %>
<%= link_to "Deny", cliq_cliq_request_path(@cliq, cliq_request), :method => :delete %>
</ul>
<% end %>
正如您自己发现的那样,使用 @cliq = Cliq.find_by(id: params[:cliq_id])
有效,而 @cliq = Cliq.find_by(params[:cliq_id])
无效。那么为什么会这样呢?
find_by
方法根据条件进行匹配。使用 find_by
,您可以匹配任何属性。例如,这也可以工作:
@cliq = Cliq.find_by(some_attribute: "foo")
因此使用 find_by
,您必须指定 id
属性以便查询 return 正确的记录。您的 find_by
查询实际上是 运行 SQL,看起来像这样:
SELECT `cliqs`.* FROM `cliqs` WHERE (2) LIMIT 1
那个select语句会return整个table,而LIMIT 1
只抓取第一条记录。
作为奖励,基于 params[:cliq_id]
分配 @cliq
的首选 rails 方法将仅使用 find
,它使用其主要搜索记录键:
@cliq = Cliq.find(params[:cliq_id])
我真的不知道如何描述这个问题,而且我以前从未遇到过这样的问题。我正在尝试建立一个 "has_many :through" 协会来处理对群组的成员资格请求。其他操作(销毁、更新)似乎工作正常。每当我在我的控制器中启动创建操作时,该对象都会显示它正在传递正确的参数并创建关联。但是,它只与 ID 为“1”的组建立关联。我不知道如何清楚地解释或解决这个问题。我会 post 我的日志和代码如下。
澄清我的问题:为什么数据 "changing" 持久化到数据库(创建时)?
Cliqs = 组
日志:
Started POST "/cliqs/2/cliq_requests" for ::1 at 2016-03-31 20:35:32 -0500
Processing by CliqRequestsController#create as HTML
Parameters: {"authenticity_token"=>"uaVHFgB7digMywl2a/n2GKMtwi691WA/dw2F2mzdkSCK69C46TZICiSp90xldj3hosFwSOPEi3fSOvOSkIVMjA==", "cliq_id"=>"2"}
Cliq Load (0.0ms) SELECT `cliqs`.* FROM `cliqs` WHERE (2) LIMIT 1
User Load (0.0ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
(0.0ms) BEGIN
SQL (1.0ms) INSERT INTO `cliq_requests` (`cliq_id`, `user_id`, `created_at`, `updated_at`) VALUES (1, 1, '2016-04-01 01:35:32', '2016-04-01 01:35:32')
(198.0ms) COMMIT
Redirected to http://localhost:3000/cliqs
Completed 302 Found in 237ms (ActiveRecord: 199.0ms)
控制器操作:
def create
@cliq = Cliq.find_by(params[:cliq_id])
@cliq_request = current_user.cliq_requests.new(cliq: @cliq)
if @cliq_request.save
redirect_to cliqs_path
else
redirect_to current_user
end
end
其他操作(以防万一):
def update
@cliq = Cliq.find_by(params[:cliq_id])
@cliq_request = CliqRequest.find(params[:id])
@cliq_request.accept
end
def destroy
@cliq = Cliq.find_by(params[:cliq_id])
@cliq_request = CliqRequest.find(params[:id])
@cliq_request.destroy
if @cliq_request.destroy
redirect_to cliqs_path
else
redirect_to current_user
end
end
还有模特们:
class User < ActiveRecord::Base
has_one :owned_cliq, foreign_key: 'owner_id', class_name: 'Cliq', dependent: :destroy
has_many :cliq_memberships, dependent: :destroy
has_many :cliqs, through: :cliq_memberships
has_many :cliq_requests, dependent: :destroy
end
class Cliq < ActiveRecord::Base
belongs_to :owner, class_name: 'User'
has_many :cliq_memberships, dependent: :destroy
has_many :members, through: :cliq_memberships, source: :user
has_many :cliq_requests, dependent: :destroy
has_many :pending_members, through: :cliq_requests, source: :user, foreign_key: 'user_id'
end
class CliqRequest < ActiveRecord::Base
#from
belongs_to :user
#to
belongs_to :cliq
def accept
cliq.members << cliq.pending_members.find(user_id)
destroy
end
end
最后是我的观点:
<h1><%= @cliq.name %></h1>
<%= link_to 'Request to join Cliq', cliq_cliq_requests_path(@cliq, @cliq_request), :method => :post %>
<% @cliq_members.each do |cliq_member| %>
<ul><%= link_to cliq_member.username, user_path(cliq_member) %></ul>
<% end %>
<h3>Cliq Requests:</h3>
<ul>
<% @cliq.pending_members.each do |pending_member| %>
<%= link_to pending_member.username, user_path(pending_member) %>
<% end %>
<% @cliq.cliq_requests.each do |cliq_request| %>
<%= link_to "Accept", cliq_cliq_request_path(@cliq, cliq_request), :method => :put %>
<%= link_to "Deny", cliq_cliq_request_path(@cliq, cliq_request), :method => :delete %>
</ul>
<% end %>
正如您自己发现的那样,使用 @cliq = Cliq.find_by(id: params[:cliq_id])
有效,而 @cliq = Cliq.find_by(params[:cliq_id])
无效。那么为什么会这样呢?
find_by
方法根据条件进行匹配。使用 find_by
,您可以匹配任何属性。例如,这也可以工作:
@cliq = Cliq.find_by(some_attribute: "foo")
因此使用 find_by
,您必须指定 id
属性以便查询 return 正确的记录。您的 find_by
查询实际上是 运行 SQL,看起来像这样:
SELECT `cliqs`.* FROM `cliqs` WHERE (2) LIMIT 1
那个select语句会return整个table,而LIMIT 1
只抓取第一条记录。
作为奖励,基于 params[:cliq_id]
分配 @cliq
的首选 rails 方法将仅使用 find
,它使用其主要搜索记录键:
@cliq = Cliq.find(params[:cliq_id])