我正在尝试学习如何在我的Rails 5应用中使用多态关联。我最近问过this问题,但是我编辑了很多次以显示我正在尝试的所有内容,它已经变得一团糟
我有一些名为Organization,Proposal和Package :: Bip的模型。
协会是:
组织
has_many :bips, as: :ipable, class_name: Package::Bip
accepts_nested_attributes_for :bips, reject_if: :all_blank, allow_destroy: true
提案
has_many :bips, as: :ipable, class_name: Package::Bip
accepts_nested_attributes_for :bips, reject_if: :all_blank, allow_destroy: true
封装:: Bip的
belongs_to :ipable, :polymorphic => true, optional: true #, inverse_of: :bip
Package :: Bip可以与Organization或Proposal相关联。我正在努力弄清楚如何在我的提案节目中展示仅属于提案的Package :: Bips,以及组织中的提案。
我的package :: bip表有这两列:
# ipable_id :integer
# ipable_type :string
ipable_type设置为Proposal或Organization。
在我的提案节目中,我有:
<% if @proposal.bips.present? %>
<%#= render @proposal.bips %>
<%= link_to proposal_package_bips_path(@proposal) do %>
<% end %>
<% end %>
我发现了this帖子。我理解这意味着我也应该尝试这个:我也尝试过:
<% if @proposal.bips.present? %>
<%= render @proposal.bips %>
<% end %>
我认为(@ proposal)应该是决定返回哪个package_bip实例的约束因素。但是,它不是。我不知道它在做什么,因为所有package_bips都会被呈现(包括与组织相关的那些)。
在我的提案控制器中,我有:
def index
@proposals = Proposal.all
# @bips = @proposal.bips
# authorize @proposals
end
def show
@bips = @proposal.bips#.where(ipable_type: 'Proposal')
end
在我的Package :: BipsController中,我有
def index
if params[:ipable_type] == "Proposal"
@bips = Package::Bip.where(:ipable_type == 'Proposal')
else params[:ipable_type] == 'Organisation'
@bips = Package::Bip.where(:ipable_type == 'Organisation')
end
但是,当我保存所有这些并尝试它时,我得到了错误的结果。
目前,db中有4个Package :: Bip实例。
Package::Bip.pluck(:ipable_type)
(0.8ms) SELECT "package_bips"."ipable_type" FROM "package_bips"
=> ["Proposal", "Proposal", "Proposal", "Organisation"]
3属于提案,1属于组织。
属于提案的3个属于不同的提案。
Package::Bip.pluck(:ipable_id)
(0.8ms) SELECT "package_bips"."ipable_id" FROM "package_bips"
=> [15, 13, 16, 1]
我的目标是提案展示视图或组织展示视图应该只显示属于该特定提案的Bips。
但是,当我渲染我的提案显示视图时,它具有:
<%= link_to proposal_package_bips_path(@proposal) do %>
反过来,我的views / package / bips / index.html.erb有:
<% @bips.each do |ip| %>
<%= ip.title.titleize %>
<%#= link_to 'More details', package_bip_path(ip) %>
我希望此视图呈现包含1个package_bip实例的列表。相反,我会列出所有4个实例(提案中的2个.bips属于不同的提案,其中一个提交属于组织)。这些都不应该在索引中呈现。
此外,我无法在bips / index.html.erb中为bips / show.html.erb添加链接。这是因为该链接看起来像:
<%= link_to 'More details', package_bip_path(ip) %> <
当我尝试使用该链接呈现索引时,我收到一条错误消息:
undefined method `package_bip_path' for #<#<Class:0x007fbce68389c0>:0x007fbcfdc31c18>
我认为链接可能需要包含提案或组织。
我的路线是嵌套的:
resources :proposals do
namespace :package do
resources :bips
end
resources :organisations do
namespace :package do
resources :bips
end
在控制台中,我可以使用我想要应用的过滤器进行搜索。
p = Proposal.last
Proposal Load (4.8ms) SELECT "proposals".* FROM "proposals" ORDER BY "proposals"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Proposal id: 16, user_id: 4, title: "test tenor", description: "test tenor", created_at: "2016-11-08 21:58:38", updated_at: "2016-11-08 21:58:38">
2.3.1p112 :199 > p.bips
Package::Bip Load (0.3ms) SELECT "package_bips".* FROM "package_bips" WHERE "package_bips"."ipable_id" = $1 AND "package_bips"."ipable_type" = $2 [["ipable_id", 16], ["ipable_type", "Proposal"]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Package::Bip id: 19, identifier: "test tenor", description: nil, conditions: "test tenor", ipable_id: 16, ipable_type: "Proposal", created_at: "2016-11-08 21:58:38", updated_at: "2016-11-08 21:58:38", title: "test tenor", status: nil, classification: "Copyright">]>
2.3.1p112 :200 > p.bips.count
(3.5ms) SELECT COUNT(*) FROM "package_bips" WHERE "package_bips"."ipable_id" = $1 AND "package_bips"."ipable_type" = $2 [["ipable_id", 16], ["ipable_type", "Proposal"]]
=> 1
但是,在我的任何尝试中,这都不会延续到代码中。
任何人都可以向我推荐资源,可以帮助我弄清楚如何设置我的多态视图,以便它们能够正确过滤,以便我可以使用典型的索引链接(例如,显示/编辑),这样他们就可以被承认属于提案/组织的一个或另一个?
更新
我现在发现了this帖子。
我尝试采用它建议的过程:
将投标控制器中的创建操作更改为:
def创建 如果params [:organisation_id] parent = Organisation.find(params [:organisation_id]) elsif params [:proposal_id] parent = Proposal.find(params [:proposal_id]) 端
bip = Package::Bip.new
Package::Bip.ipable = parent
# @bip = Package::Bip.new(bip_params)
# authorize @bip
respond_to do |format|
if @bip.save
format.html { redirect_to @bip }
format.json { render :show, status: :created, location: @bip }
else
format.html { render :new }
format.json { render json: @bip.errors, status: :unprocessable_entity }
end
end
端
将提案视图更改为:
当我尝试这个时,我没有得到任何错误,但是所有的Package :: Bips都显示在提案显示视图中。
尽管存在具有组织ID的Package :: Bips。
Package::Bip.all.pluck(:ipable_type)
(0.9ms) SELECT "package_bips"."ipable_type" FROM "package_bips"
=> ["Proposal", "Proposal", "Proposal", "Organisation", "Proposal"]
当我重新启动服务器并再试一次时,我收到一条错误消息:
undefined method `empty?' for #<Class:0x007ff20920e218>
错误消息指向我的新行:
<%= polymorphic_path(@proposal, Package::Bip) %>
日志显示:
Started POST "/__better_errors/3f34303f5f5c670f/variables" for ::1 at 2016-11-13 10:58:13 +1100
Package::Bip Load (0.4ms) SELECT "package_bips".* FROM "package_bips" WHERE "package_bips"."ipable_id" = $1 AND "package_bips"."ipable_type" = $2 [["ipable_id", 15], ["ipable_type", "Proposal"]]
此post显示了类似的问题,可通过添加&#39; []&#39;来解决。走的路。
然后我尝试:
<%= link_to polymorphic_path([@proposal, Package::Bip]) do %>
我仍然会获得所有bips的列表(即使属于某个组织或具有不同ID的提案)。
我从日志中可以看到的可能是一条线索(如果是 - 它超越了我的头脑)。
Started GET "/proposals/15/package/bips" for ::1 at 2016-11-13 11:24:32 +1100
Processing by Package::BipsController#index as HTML
Parameters: {"proposal_id"=>"15"}
User Load (1.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2 [["id", 4], ["LIMIT", 1]]
Rendering package/bips/index.html.erb within layouts/application
Package::Bip Load (0.6ms) SELECT "package_bips".* FROM "package_bips"
Rendered package/bips/index.html.erb within layouts/application (5.4ms)
日志似乎没有显示任何迹象表明它正在将提案或提案ID过滤器应用于package_bips。
这对我没有任何意义,因为我的路线只提供组织或提案的前缀:
rake routes | grep package_bip
organisation_package_bips GET /organisations/:organisation_id/package/bips(.:format) package/bips#index
new_organisation_package_bip GET /organisations/:organisation_id/package/bips/new(.:format) package/bips#new
edit_organisation_package_bip GET /organisations/:organisation_id/package/bips/:id/edit(.:format) package/bips#edit
organisation_package_bip GET /organisations/:organisation_id/package/bips/:id(.:format) package/bips#show
proposal_package_bips GET /proposals/:proposal_id/package/bips(.:format) package/bips#index
new_proposal_package_bip GET /proposals/:proposal_id/package/bips/new(.:format) package/bips#new
edit_proposal_package_bip GET /proposals/:proposal_id/package/bips/:id/edit(.:format) package/bips#edit
proposal_package_bip GET /proposals/:proposal_id/package/bips/:id(.:format) package/bips#show
此外,当我尝试在最后一个链接的帖子中使用show path时,在我的views / package / bips / index.html.erb中:
<% @bips.each do |ip| %>
<%= link_to polymorphic_path([@ipable, ip]) %>
然后我得到一个错误,上面写着:
undefined method `package_bip_path' for #<#<Class:0x007f9e8ac29248>:0x007f9e939c9508>
TARYN&#39; S寻找问题的建议
背景。在我的提案控制器中,我的提案被定义为:
def set_proposal
@proposal = Proposal.find(params[:id])
end
在控制台中,我尝试:
params = {:proposal_id => 15}
=> {:proposal_id=>15}
2.3.1p112 :031 > @proposal = Proposal.find(params[:proposal_id])
Proposal Load (0.7ms) SELECT "proposals".* FROM "proposals" WHERE "proposals"."id" = $1 LIMIT $2 [["id", 15], ["LIMIT", 1]]
=> #<Proposal id: 15, user_id: 4, title: "testing filter", description: "testing filter", byline: "testing filter", nda_required: true, created_at: "2016-11-08 00:59:09", updated_at: "2016-11-08 00:59:09">
2.3.1p112 :033 > @proposal.bips
Package::Bip Load (0.7ms) SELECT "package_bips".* FROM "package_bips" WHERE "package_bips"."ipable_id" = $1 AND "package_bips"."ipable_type" = $2 [["ipable_id", 15], ["ipable_type", "Proposal"]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Package::Bip id: 17, identifier: "testing filter", description: nil, conditions: "testing filter", ipable_id: 15, ipable_type: "Proposal", created_at: "2016-11-08 00:59:09", updated_at: "2016-11-08 00:59:09", title: "testing filter", status: nil, classification: "Patent">, #<Package::Bip id: 21, identifier: "dd", description: nil, conditions: "dd", ipable_id: 15, ipable_type: "Proposal", created_at: "2016-11-10 22:47:54", updated_at: "2016-11-10 22:47:54", title: "ldsjflkjklsdjfl", status: nil, classification: "Design">]>
2.3.1p112 :034 > @proposal.bips.count
(6.3ms) SELECT COUNT(*) FROM "package_bips" WHERE "package_bips"."ipable_id" = $1 AND "package_bips"."ipable_type" = $2 [["ipable_id", 15], ["ipable_type", "Proposal"]]
=> 2
这给出了正确的结果。
在提案控制器中,显示操作,我有:
def show
@images = @proposal.images
byebug
puts 'testing proposal controller'
@bips = @proposal.bips#.where(ipable_type: 'Proposal')
end
当我尝试这个时,我可以探索提案参数:
params
<ActionController::Parameters {"controller"=>"proposals", "action"=>"show", "id"=>"15"} permitted: false>
(byebug) proposal_params
*** ActionController::ParameterMissing Exception: param is missing or the value is empty: proposal
nil
有这个问题的其他人将其归因于&#39;要求&#39;在他们强有力的params方法中的陈述。
我的proposal_params定义为:
def proposal_params
params.require(:proposal).permit(:title, :description, :byline, :nda_required, :randd_maturities_list,
#Package
bips_attributes: [:id, :status, :classification, :identifier, :conditions, :title, :_destroy,
tenor_attributes: [:id, :express_interest, :commencement, :expiry, :enduring, :repeat, :frequency, :_destroy]
],
)
end
我认为是正确的。
这些消息很奇怪,因为我也可以通过再见错误声明中的每个列入白名单的项目并获得正确的响应。例如:
@proposal.id
15
当我尝试使用Package :: bips控制器中的bye bug进行探索时,我可以看到:
params.inspect
"<ActionController::Parameters {\"controller\"=>\"package/bips\", \"action\"=>\"index\", \"proposal_id\"=>\"15\"} permitted: false>"
允许的:false属性似乎是我的代码中的一个问题。
这是我的下一行调查。
答案 0 :(得分:2)
答案在这里:https://rubyplus.com/articles/3901-Polymorphic-Association-in-Rails-5
这个技巧似乎是在文章中显示的load_commentable方法中。对我来说太复杂了,但它确实有效。
非常感谢那些乐于分享他们所知道的人的帮助。谢谢Taryn&amp;巴拉。