Rails 5 – 使用多态关联 – 呈现视图

我正在尝试学习如何在我的Rails 5应用程序中使用多态关联。 我最近问过这个问题,但是我编辑了很多次来展示我正在尝试的所有东西,它变得一团糟

我有一个名为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 

套票:必必

 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。

在我的提案节目中,我有:

      

我找到了这篇文章。 我理解这意味着我也应该能够尝试这个:我也尝试过:

    

我认为(@ 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。

但是,当我渲染我的提案显示视图时,它具有:

  

反过来,我的views / package / bips / index.html.erb有:

    

我希望这个视图呈现一个包含1个package_bip实例的列表。 相反,我会列出所有4个实例(提案中的2个.bips属于不同的提案,其中一个提交属于组织)。 这些都不应该在索引中呈现。

此外,我无法在bips / index.html.erb中添加bips / show.html.erb中的链接。 这是因为该链接看起来像:

  < 

当我尝试使用该链接呈现索引时,我收到一条错误消息:

 undefined method `package_bip_path' for #<#:0x007fbcfdc31c18> 

我想这个链接可能需要包括提案或组织。

我的路线是嵌套的:

 resources :proposals do namespace :package do resources :bips end resources :organisations do namespace :package do resources :bips end 

从控制台,我可以使用我想要应用的filter进行搜索。

 p = Proposal.last Proposal Load (4.8ms) SELECT "proposals".* FROM "proposals" ORDER BY "proposals"."id" DESC LIMIT $1 [["LIMIT", 1]] => # 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 [#]> 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 

但是,在我的任何尝试中,这都不会延续到代码中。

任何人都可以向我推荐资源,可以帮助我弄清楚如何设置我的多态视图,以便它们正常过滤,以便我可以使用典型的索引链接(例如,显示/编辑),以便它们可以被识别为属于提案/组织的一个或另一个?

UPDATE

我现在发现了这篇文章。

我尝试采用它建议的过程:

  1. 将提案控制器中的创建操作更改为:

    def create if params [:organisation_id] parent = Organisation.find(params [:organisation_id])elsif params [:proposal_id] parent = Proposal.find(params [:proposal_id])end

     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 

    结束

  2. 将提案视图更改为:

当我尝试这个时,我没有得到任何错误,但是所有的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 # 

错误消息指向我的新行:

  

日志显示:

 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"]] 

这篇文章显示了一个类似的问题,通过在路径中添加'[]’来解决。

当我尝试:

  

我仍然得到所有bips的列表(即使属于组织或具有不同id的提议的bips)。

我可以从日志中看到的可能是一个线索(如果是 – 它超越我的头脑)。

 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) 

日志似乎没有显示任何迹象表明它正在将提案或提案IDfilter应用于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 

更进一步,当我尝试在最后一个链接的post中使用show path时,在我的views / package / bips / index.html.erb中:

    

然后我得到一个错误,上面写着:

 undefined method `package_bip_path' for #<#:0x007f9e939c9508> 

TARYN对于寻找问题的建议

背景。 在我的提案控制器中,我的提案定义为:

 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]] => # 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 [#, #]> 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 "proposals", "action"=>"show", "id"=>"15"} permitted: false> (byebug) proposal_params *** ActionController::ParameterMissing Exception: param is missing or the value is empty: proposal nil 

其他有此问题的人将其归因于强params方法中的’require’语句。

我的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 "\"package/bips\", \"action\"=>\"index\", \"proposal_id\"=>\"15\"} permitted: false>" 

允许的:false属性似乎是我的代码中的问题。

这是我的下一行调查。

答案在这里: https : //rubyplus.com/articles/3901-Polymorphic-Association-in-Rails-5

技巧似乎是在文章中显示的load_commentable方法中。 对我来说太复杂了,但它确实有效。

非常感谢人们乐于分享他们所知道的有多少帮助。 谢谢Taryn&Bala。