2016-11-10 48 views
4

我試圖學習如何在Rails 5應用程序中使用多態關聯。我最近問了this的問題,但我編輯了很多次,以顯示我正在嘗試的所有東西,它已變得凌亂Rails 5 - 使用多態關聯 - 呈現視圖

我有模型,稱爲組織,建議和包:: 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 

套票:必必可與組織相關聯或道具OSAL。我正在努力弄清楚如何在我的提案展示中顯示只屬於提案的Package :: Bips,並且對於組織而言也是如此。

我的包:: BIP表中有這2列:

# ipable_id  :integer 
# ipable_type :string 

的ipable_type被設置爲提案或組織。

在我的提議顯示,我有:

<% 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_bip都被渲染(包括那些與組織相關的)。

在我的提議控制器,我有:

def index 
    @proposals = Proposal.all 
    # @bips = @proposal.bips 
    # authorize @proposals 
    end 


def show 
    @bips = @proposal.bips#.where(ipable_type: 'Proposal') 
end 

在我的包:: 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 %> 

反過來,我的意見/包/ BIPS/index.html.erb有:

<% @bips.each do |ip| %> 
    <%= ip.title.titleize %> 
     <%#= link_to 'More details', package_bip_path(ip) %> 

我期待這個視圖呈現一個包含1個package_bip實例的列表。相反,我會列出所有4個實例(提案中的2個.bip屬於不同的提案,其中一個屬於組織)。這些都不應該在指數中呈現。

此外,我無法在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 

但是,這不會延續到我的任何嘗試中的代碼。

任何人都可以引用我的資源,可以幫助我弄清楚如何設置我的多態視圖,以便他們工作正確過濾,以便我可以使用典型的索引鏈接(例如,顯示/編輯),以便他們可以被認爲屬於提案/組織的一個或另一個?

UPDATE

我現在已經找到this後。

我試圖採用它表明由該方法:

  1. 改變創建在提案中控制器動作:

    DEF創建 如果PARAMS [:organisation_id] 父= Organisation.find(PARAMS [ :organisation_id]) ELSIF PARAMS [:PROPOSAL_ID] 父= 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 
    

  2. 更改提議視圖:

當我嘗試這一點,我沒有錯誤,但所有套票:BIPS的顯示在提案放映視圖。

儘管有Package :: Bips有組織ID。

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

This 顯示了一個類似的問題,可以通過在路徑中添加'[]'來解決。

當我再試試:

<%= 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道路在過去的鏈接後在我的意見/包/ BIPS/index.html.erb爲:

<% @bips.each do |ip| %> 
    <%= link_to polymorphic_path([@ipable, ip]) %> 

然後我得到一個錯誤,說:

undefined method `package_bip_path' for #<#<Class:0x007f9e8ac29248>: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]] 
=> #<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:誰擁有這個問題

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 

其他人歸因於它的'強制性參數法'中的'要求'聲明。

我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 

我認爲它是正確的。

這些消息很奇怪,因爲我也可以通過再見bug聲明中的每個白名單項並獲得正確的響應。例如:

@proposal.id 
15 

當我嘗試在包再見錯誤:: BIPS控制器,索引操作探索,我可以看到:

params.inspect 
"<ActionController::Parameters {\"controller\"=>\"package/bips\", \"action\"=>\"index\", \"proposal_id\"=>\"15\"} permitted: false>" 

允許的:false屬性似乎是一個問題的所有在我的代碼上。

這是我的下一個問題。

+0

好的,所以你現在沒有向我們展示如何在控制器中設置'@ proposal'。 (它可能不相關,但我們會看到)。在你的控制檯中,如果你從字面上去做你的控制器會做的事情,比如'p = Proposal.last','params = {:proposal_id => 0}',那麼'@proposal = Proposal.find (params [:proposal_id])'(或任何在你的控制器中)。然後嘗試'@ proposal.bips'。 –

+0

(注意:有些數據庫在id爲0(甚至是1)時會做些有趣的事情,這就是爲什麼我故意使用這個例子 - 它可以假設你的意思是「全部」而不是實際記錄,ID爲0 ) –

+0

下一步 - 在您的控制器代碼中添加一大堆調試語句,以檢查正在運行的代碼以及每個點處的值,例如'puts「我在show controller中使用@proposal:#{ @ proposal.inspect}和@bips:#{@ bips.inspect}「' - 這就是你將如何發現不一致的地方 –

回答