【问题标题】:rails - association params selected, but params "changing" on persistrails - 选择了关联参数,但参数“改变”持续存在
【发布时间】:2016-04-01 01:52:11
【问题描述】:

我真的不知道如何描述这个问题,而且我以前从未遇到过这样的问题。我正在尝试建立一个“has_many :through”关联来处理对组的成员资格请求。其他操作(销毁、更新)似乎工作正常。每当我在控制器中启动创建操作时,对象都会显示它正在传递正确的参数并创建了关联。但是,它只与具有“1”id 的组创建关联。我不知道如何清楚地解释或解决这个问题。我将在下面发布我的日志和代码。

澄清我的问题:为什么数据在保存到数据库时会“改变”(在创建时)?

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 %>

【问题讨论】:

  • 尝试在 create 方法中分配 @cliq 后立即使用 byebug 对其进行检查。它的 id 是什么?
  • 奇怪的是,我只是觉得我修好了。让我知道您对此有何看法:我将在更新操作中查找 Cliq 的代码更改为“cliq = Cliq.find_by(id: params[:cliq_id])”而不是“cliq = Cliq.find_by(params[: cliq_id])"。为什么会这样?
  • 我会包括一个答案,一秒

标签: mysql ruby-on-rails ruby-on-rails-4 activerecord associations


【解决方案1】:

正如您自己发现的那样,使用 @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 属性才能使查询返回正确的记录。您的 find_by 查询实际上正在运行看起来像这样的 SQL:

SELECT  `cliqs`.* FROM `cliqs` WHERE (2) LIMIT 1

该 select 语句将返回整个表,LIMIT 1 只是抓取第一条记录。

作为奖励,基于params[:cliq_id] 分配@cliq 的首选Rails 方法是仅使用find,它使用其主键搜索记录:

@cliq = Cliq.find(params[:cliq_id])

【讨论】:

  • 噢噢噢!好的,我明白了。我只是为了清楚起见而这样做,它似乎也更清楚地工作了。非常感谢您的解释!一个接受的答案和一个赞成你,格伦可可!你去格伦可可!
猜你喜欢
  • 1970-01-01
  • 2013-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多