我试图学习如何在我的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
封装:: 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
类型设置为Proposal或Organization。
在我的提案节目中,我有:
<% if @proposal.bips.present? %>
<%= link_to package_bips_path(@proposal) do %>
<% end %>
我认为(@ proposal)应该是决定返回哪个package_bip实例的约束因素。但是,它不是。我不知道它在做什么,因为所有package_bips都会被呈现(包括与组织相关的那些)。
在我的提案控制器中,我有:
def show
@images = @proposal.images
@bips = @proposal.bips.where(ipable_type: 'Proposal')
end
我添加了上面的范围,试图强制show只使用在ipable_type属性中设置Proposal的那些 - 但是没有任何帮助。
我不确定我是否应该在Package :: Bips控制器中创建一个if语句来查看ipable_type是否是提案。我不了解如何取消多态对象的关联实例,以便我可以在提案显示页面的索引中显示相关的实例(索引仅填充属于提案的实例)。
我尝试将Package :: Bips控制器的索引操作编写为:
def index
if params[:ipable_type]
@bips = Package::Bip.where(ipable_type: 'Proposal')
elsif params[:ipable_type]
@bips = Package::Bip.where(ipable_type: 'Organisation')
else
@bips = Package::Bip.all
end
# authorize @bips
end
根本没有做任何事情。所以我不确定为什么它至少不会给出错误信息。
渲染正确的观点
在我的提案/节目中 - 我有:
<%= link_to package_bips_path(@proposal) do %>
该链接转到我的views / package / bips / index.html。该观点有:
<% @bips.each do |ip| %>.
目前列出了所有的bips(组织和提案)。我认为提案/节目中链接中的@proposal可能会限制事物,或者我的bips控制器中的索引操作方法可能(上图)可能会有所帮助。但这些都不会过滤实例。
如果我写:
<%= @proposal.bips.first.title %>
在我的提案显示视图中,它可以渲染标题。
现在我的挑战是如何让双向索引视图呈现正确的实例集(仅提议或仅组织),具体取决于发送请求以呈现该视图的页面。也许我可以编写请求引用来查看它的组织控制器或提议控制器是否请求?
尝试提供观点
视图/提案/ show.html.erb
<% if @proposal.bips.present? %>
<%= link_to package_bips_path(@proposal) do %>
<h6 style="margin:2%; "> Intellectual Property </h6>
<% end %>
<% end %>
视图/ BIPS / index.html.erb
<% @bips.each do |ip| %>
<%= ip.title.titleize %>
<%= ip.classification.humanize %>
<% end %>
视图/ BIPS / show.html.erb
<%= @bip.title.titleize %></h5><p><%= @bip.status %>
提案控制器
def index
@proposals = Proposal.all
# @bips = @proposal.bips
# authorize @proposals
end
def show
@images = @proposal.images
@bips = @proposal.bips#.where(ipable_type: 'Proposal')
end
bips controller
def index
# if params[:status]
# @bips = Package::Bip.where(:status => params[:status])
# else
# @bips = Package::Bip.all
# end
if params[:ipable_type]
@bips = Package::Bip.where(ipable_type: 'Proposal')
elsif params[:ipable_type]
@bips = Package::Bip.where(ipable_type: 'Organisation')
else
@bips = Package::Bip.all
end
# authorize @bips
end
新尝试
我发现了这个:
http://rails-bestpractices.com/posts/2010/09/23/generate-polymorphic-url/
我不明白父母是否&#39;本文中使用的是某种关键字,或者我需要在某处定义它。
我试图嵌套我的路线,所以现在:
resources :proposals do
namespace :package do
resources :materials
resources :insights
resources :facilities
resources :participants
resources :fundings
resources :facts
resources :bips
end
......和组织一样。
但是,我收到了错误。我想也许这篇文章已经向前迈了几步。是否有使用多态路径的约定?
我现在找到了这个资源:
http://www.codequizzes.com/rails/learn-rails/polymorphism
创建动作对我来说很不寻常。任何人都可以解释这种方法中使用的创建动作概念吗?
下次尝试
Package :: Bips控制器中的新索引操作:
def index
if Package::Bip.ipable_type: 'Proposal'
@bips = Package::Bip.where(ipable_type: 'Proposal')
elsif Package::Bip.ipable_type: 'Organisation'
@bips = Package::Bip.where(ipable_type: 'Organisation')
else
@bips = Package::Bip.all
end
但现在,仍然没有让我试着看看它是否有效。
当我尝试为提案呈现展示视图时,出现错误消息:
undefined method `package_bips_path' for #<#<Class:0x007fa72ea9b730>:0x007fa72ea93ee0>
这是展示页面包含的链接:
<% if @proposal.bips.present? %>
<%= link_to package_bips_path(@proposal) do %>
<h6 style="margin:2%; "> Intellectual Property </h6>
<% end %>
另一个人
bips controller,index action:
if params[:ipable_type] == 'Proposal'
@bips = Package::Bip.where(ipable_type: 'Proposal')
else params[:ipable_type] == 'Organisation'
@bips = Package::Bip.where(ipable_type: 'Organisation')
# else
# @bips = Package::Bip.all
end
提案显示:
<% if @proposal.bips.present? %>
<%= link_to proposal_package_bips_path(@proposal) do %>
<% end %>
<% end %>
视图/ BIPS /索引
<div class="container-fluid" style="margin-bottom: 50px">
<h2 style="text-align: center">Intellectual Property Assets</h2>
<div class="row">
<div class="col-sm-10 col-sm-offset-1">
<div class="row" style="margin-top:50px; margin-bottom:50px">
<div class="col-md-8 col-md-offset-2">
<span style="margin-right:50px; padding-left:50px">
<%= link_to "All", action: :index %>
</span>
<span style="color:grey">·</span>
<span style="margin-right:50px; padding-left:50px">
<%#= link_to "Intellectual Property we can offer", package_bips_path(:status => "Offered") %>
</span>
<span style="color:grey">·</span>
<span style="margin-right:50px; padding-left:50px">
<%#= link_to "Intellectual Property sought", package_bips_path(:status => "Sought") %>
</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-10 col-xs-offset-1">
<div class="table-responsive" style="margin-left:30px; margin-top:15px">
<table class="table table-bordered">
<tr>
<td> <h5>Title</h5> </td>
<td> <h5>Asset</h5> </td>
<td> <h5>Added</h5> </td>
<%# if policy(@package_ips).update? %>
<td> <h5>Manage this asset</h5></td>
<%# end %>
</tr>
<% @bips.each do |ip| %>
<tr>
<td>
<%= ip.title.titleize %>
</td>
<td>
<%= ip.classification.humanize %>
</td>
<td>
<%= ip.created_at.try(:strftime, '%e %B %Y') %>
</td>
<%# if policy(@package_ips).update? %>
<td>
<%#= link_to 'More details', package_bip_path(ip) %> <span style="color:grey">·</span>
<%#= link_to "Edit", edit_package_ip_organistion_path(@organisation) %>
<!-- <span style="color:grey">·</span> -->
<%#= link_to 'Destroy', ip, method: :delete, data: { confirm: 'Are you sure?' } %>
</td>
<%# end %>
</tr>
<% end %>
</table>
</div>
</div>
</div>
</div>
这不起作用(仍然呈现错误的bips),但除了不正确之外,我在显示页面上没有任何链接。如果我想链接到:bips show view上的status params,它从一个没有提案/组织前缀的路径开始 - 所以它不起作用。
下次尝试
bips controller index action现在有:
if params[:ipable_type] == "Proposal"
@bips = Package::Bip.where(:ipable_type == 'Proposal')
else params[:ipable_type] == 'Organisation'
@bips = Package::Bip.where(:ipable_type == 'Organisation')
这现在呈现bips,但它会在组织索引(以及提案索引)中呈现提案bips。
我被卡住了!
在控制台中,我可以这样做:
p = Proposal.last
Proposal Load (6.1ms) SELECT "proposals".* FROM "proposals" ORDER BY "proposals"."id" DESC LIMIT $1 [["LIMIT", 1]]
=> #<Proposal id: 15, user_id: 4, title: "testing filter", created_at: "2016-11-08 00:59:09", updated_at: "2016-11-08 00:59:09">
2.3.1p112 :123 > p.bips
Package::Bip Load (0.5ms) 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", ipable_id: 15, ipable_type: "Proposal", created_at: "2016-11-08 00:59:09", updated_at: "2016-11-08 00:59:09"]>
这是对的。我也可以这样做:
o = Organisation.first
Organisation Load (1.1ms) SELECT "organisations".* FROM "organisations" ORDER BY "organisations"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<Organisation id: 1, title: "bhjhghdddd", created_at: "2016-10-21 05:20:39", updated_at: "2016-11-06 21:36:30">
2.3.1p112 :125 > o.bips
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", 1], ["ipable_type", "Organisation"]]
=> #<ActiveRecord::Associations::CollectionProxy []>
这也是正确的。
我无法找到一种方法来在代码中使用正确的bips填充索引。
另一个尝试
我尝试使用本教程中的建议:http://www.codequizzes.com/rails/learn-rails/polymorphism
它表明:
# views/articles/show.html.erb
<%= render @article.comments %>
# views/comments/_comment.html.erb
<%= comment.body %><br />
The render @article.comments in the show page automatically knows to load a file called views/comments/_comment.html.erb. This is Rails magic, so just memorize this.
考虑到这一点,我在我的views / package / bips文件夹中做了一个名为_bips.html.erb的文件。
在我的提案显示视图中,我尝试过:
<%= render @proposal.bips %>
我收到错误消息:
Missing partial package/bips/_bip with {:locale=>[:en], :formats=>[:html], :variants=>[], :handlers=>[:raw, :erb, :html, :builder, :ruby, :coffee, :jbuilder]}. Searched in:
* "/Users/d/cv/cflive/app/views"
这是正确的位置。我想知道这个问题是否与嵌套路由有关。我的路线文件现在有:
resources :proposals do
namespace :package do
resources :bips
end
谁能明白为什么这种方法不起作用?