在 Rails 中连接关联的按钮不起作用。所有权转让
Posted
技术标签:
【中文标题】在 Rails 中连接关联的按钮不起作用。所有权转让【英文标题】:Button to connect an association in Rails is not working. Transfer of ownership 【发布时间】:2021-11-02 01:58:26 【问题描述】:我正在处理我的第一个 Rails 项目,一个采用应用程序,并试图将关联与 Rails 中的新潜在所有者联系起来。我的控制器操作正在通过我的收养请求方法进行,但没有任何更改被持久保存到我在 ActiveRecord 中的联接表中。有人可以告诉我我在这里缺少什么吗?
应用程序:
所有者注册或登录到他们的帐户。他们可以使用表格添加他们的雪貂。稍后,所有者可能想要创建一个机会列表来收养/重新安置他们的动物。浏览的人应该能够点击他们感兴趣的 Opportunity,这应该在连接表 Opportunity 中建立关联,:adopter_id。
我的模特:
class Owner < ApplicationRecord
has_secure_password
has_many :ferrets, dependent: :destroy
has_many :opportunities, dependent: :destroy
has_many :ferret_adoptions, through: :opportunities, source: :ferret
accepts_nested_attributes_for :ferrets, :opportunities
end
class Ferret < ApplicationRecord
belongs_to :owner
has_many :opportunities
has_many :owners, through: :opportunities
end
class Opportunity < ApplicationRecord
belongs_to :ferret
belongs_to :owner
end
在 Opportunities Controller 中,我的 admission_request 方法:
def adoption_request
@owner = Owner.find(session[:owner_id])
@opportunity = Opportunity.find(params[:id])
@opportunity.adopter_id = [] << current_user.id
current_user.req_id = [] << @opportunity.id
flash[:message] = "Adoption request submitted."
redirect_to questions_path
end
我正在使用一个按钮来执行此操作,但如果有更好的效果,我愿意更改它:
<button><%= link_to 'Adoption Request', adoption_request_path, method: :post %> <i class='fas fa-heart' style='color:crimson'></i></button>
作为所有者,当我单击按钮提出采用请求时,我看到了 byebug 中的所有工作部分,并且我被重定向到带有成功消息的下一页,好像一切正常,但没有关联实际上被持久化到数据库中。
感谢您提供的任何反馈。
【问题讨论】:
我认为您需要致电save
才能使任何分配持续存在。
current_user.req_id = [] << @opportunity.id
这应该做什么?
@opportunity.adopter_id = current_user.id
。或@opportunity.adopter_id = ([] << current_user.id)[0]
以获得最大的愚蠢。尽管[] <<
是一种非常奇怪的声明数组的方式,但很严肃。尤其是当您不需要数组时。
我希望将 owner.id 作为机会.adopter_id 保存在连接表中以完成关联。以下是可选的,不过最好将Owner记录中的opportunity.id保存为req_id作为请求的记录。
好的,我想我可能已经解决了这个问题。我确实在考虑数组,并读到铲子方法应该自动保存在 Rails 中。但我根本不需要这样做。我刚刚分配了它 = 新的关联显示在控制台中。
【参考方案1】:
我在这里假设 Opportunity 应该代表类似于列表的东西(它需要一个不那么模糊的名称)。
如果是这样,如果您希望多个用户能够响应机会,则您缺少模型及其表:
class Owner < ApplicationRecord
has_secure_password
has_many :ferrets, dependent: :destroy
has_many :opportunities, dependent: :destroy
has_many :adoption_requests_as_adopter,
foreign_key: :adopter_id,
class_name: 'AdoptionRequest'
has_many :adoption_requests_as_owner,
through: :opportunities,
source: :adoption_requests
accepts_nested_attributes_for :ferrets, :opportunities
end
class Ferret < ApplicationRecord
belongs_to :owner
has_many :opportunities
has_many :owners, through: :opportunities
has_many :adoption_requests, through: :opportunities
end
class Opportunity < ApplicationRecord
belongs_to :ferret
belongs_to :owner
has_many :adoption_requests
end
class AdoptionRequest < ApplicationRecord
belongs_to :adopter, class_name: 'Owner' # ???
belongs_to :opportunity
has_one :ferret, through: :opportunity
has_one :owner, through: :opportunity
end
如果您的opportunities
表中只有一个adopter_id
,则它只能保存一个值。
我只是将路由/控制器设置为嵌套资源的普通 CRUD 控制器:
# routes.rb
resources :opportunities do
resources :adoption_requests, only: [:create, :index]
end
<%= button_to "Adopt this ferret", opportunity_adoption_requests_path(@opportunity), method: :post %>
class AdoptionRequestsController < ApplicationController
before_action :set_opportunity
# @todo authorize so that it can only be viewed by the owner
# GET /opportunities/1/adoption_requests
def index
@adoption_requests = @opportunity.adoption_requests
end
# @todo authorize so that a current owner can't create adoption_requests
# for their own ferrets
# POST /opportunities/1/adoption_requests
def create
@adoption_request = @opportunity.adoption_requests.new(
adopter: current_user
)
if @adoption_request.save
redirect_to @opportunity, notice: 'Thank you for your reply! The owner of the ferret will be notified.'
# @todo send notification to owner
else
redirect_to @opportunity, notice: 'Oh noes!'
end
end
private
def set_opportunity
@opportunity = Opportunity.find(params[:opportunity_id])
end
end
只有在所有者实际接受收养请求时,您才会真正更新机会,这是以后的单独问题。
【讨论】:
在我工作的过程中,我意识到需要一个额外的表,但是这些关系很难让我理解。非常感谢您在这里的反馈。 如果您尝试将其视为域中的实际对象而不是连接表,并且在开始编写域之前使用记事本或 UML 工具勾勒出域,这会有所帮助代码。以上是关于在 Rails 中连接关联的按钮不起作用。所有权转让的主要内容,如果未能解决你的问题,请参考以下文章
使用dependent: :destroy 在rails 上不起作用