Railsで複数のhas_manyを持ったモデルを作りたい


多くのlibrary（製品）があり、それぞれのlibraryには多くのdoc（書類が）あります。またそれぞれの製品に多くのpict(画像）がある。  
二つに分けたいのは書類は種類や備考がありますが、pictはサムネールの表示をしたいからです。

library.rb

[code]

    has_many :docs
    has_many :picts
    
[/code]

doc.rb

[code]

    belongs_to :library
    
[/code]

pict.rb

[code]

    belongs_to :library
    
[/code]

としてあります。ここでlibraryコントローラーで

[code]

    def show
      @docs = @library.docs.where(params[:library_id])
    end
    
    def pictshow　#ルーティングの設定はしてある
      @picts = @library.picts.where(params[:library_id])
    end
    
[/code]

になっておりますが、showではエラーが出ないのですが、pictshowで

[code]

    NoMethodError in LibrariesController#pictshow
    undefined method `picts' for nil:NilClass
    
[/code]

になってしまいます。原因が解りません




>
[code]

>     NoMethodError in LibrariesController#pictshow
>     undefined method `picts' for nil:NilClass
>  
[/code]

`@library`が`nil`なので`@library.picts`が`NoMethodErrorになっています。

scaffoldで生成したコントローラであればコードはこうなっていると思います。

[code]

    class LibrariesController < ApplicationController
      before_action :set_library, only: [:show, :edit, :update, :destroy]
    
      def show
      end
    
      private
        # Use callbacks to share common setup or constraints between actions.
        def set_library
          @library = Library.find(params[:id])
        end
    end
    
[/code]

`set_library`メソッドによって`@library`に然るべきidのLibraryがロードされるのですが、`set_library`が呼び出されるのは

[code]

      before_action :set_library, only: [:show, :edit, :update, :destroy]
    
[/code]

と、ここで指定されたメソッド(アクション)のみです。自分で追加したメソッドであれば、`before_action`にもそれを追加しないと`@library`は設定されないまま(参照したら`nil`)になります。

ついでに指摘しておきます

[code]

    @docs = @library.docs.where(params[:library_id])
    
[/code]

というコードですが、`@library.docs`は

[code]

    @docs = Doc.where(library_id: @library.id)
    
[/code]

と同じです。多分やりたいことは

[code]

     @docs = @library.docs
    
[/code]

で十分なんじゃないでしょうか。

さらに言うと、`where(params[:library_id])`は多分`where(10)`とかになるので、意図しないクエリになっていると思います。

(暗黙の型変換でSQLとしては`SELECT ... WHERE TRUE`になってるかな？)




`@picts = @library.picts`
の時点で値が`nil`になっています。該当の`@library`が一枚も`pict`を持っていないためです。

