0

このエラーは、何週間も私を悩ませてきました。Item指定した and からを構築しようとするUserListItemは作成されますが、関連付けは作成されWishません。

私がやろうとする@item.lists.first.nameと、エラーが返されます:

undefined method 'name' for nil:NilClass

私はレールに非常に慣れていないので、見逃したり誤解したりしているものがあると確信しています。したがって、どんな助けも大歓迎です!

私は4つのモデルを持っています:

class User < ActiveRecord::Base
  has_many :lists, dependent: :destroy
  has_many :wishes, through: :lists
  has_many :items, through: :wishes

class List < ActiveRecord::Base
  belongs_to :user
  has_many :wishes, dependent: :destroy
  has_many :items, through: :wishes

class Wish < ActiveRecord::Base
  belongs_to :list
  belongs_to :item

class Item < ActiveRecord::Base
  has_many :wishes
  has_many :lists, through: :wishes

Item新しいfrom lists_controller.rbshow アクションを作成したい:

class ListsController < ApplicationController
  def show
    @user = User.find(params[:user_id])
    @list = @user.lists.find(params[:id])
    @item = @list.items.build if current_user?(@user)
    @items = @list.items
  end

class ItemsController < ApplicationController
    def create
        @list = current_user.lists.find(params[:list_id])
        @item = @list.items.build(params[:item])
    if @item.save
      flash[:success] = "Item created!"
      redirect_to @item
    else
      render 'new'
    end
end

私のルートファイルは次のようになります。

Wishlist::Application.routes.draw do
  resources :users do
    resources :lists, only: [:show, :create, :destroy]
  end
  resources :items, only: [:show, :new, :create, :destroy]

フォームlists/show.html.erb:

   <div class="modal-body">
     <%= form_for(@item, html: { multipart: true }) do |f| %>
  <div class="field">
        <%= render 'items/fields', f: f %>
         <%= hidden_field_tag :list_id, @list.id %>
  </div>
   </div>

items/fields:

<%= render 'shared/error_messages', object: f.object %>

<%= f.label :image %>
<%= f.file_field :image %>

<%= f.label :remote_image_url, "or image URL" %>
<%= f.text_field :remote_image_url %>

<%= f.label :title %>
<%= f.text_field :title %>

<%= f.label :link %>
<%= f.text_field :link %>

アップデート

ログから:

Processing by ItemsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"pcDVdaDzZz4M17Kwjx8mKw6tTF9MjUvx1woTzaKRWJY=", "item"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x007fecdd1fd890 @original_filename="profile.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"item[image]\"; filename=\"profile.jpg\"\r\nContent-Type: image/jpeg\r\n", @tempfile=#<File:/var/folders/6y/j8zfcgmd02x5s439c0np8fjh0000gn/T/RackMultipart20130216-8413-3vzjuj>>, "remote_image_url"=>"", "title"=>"YES", "link"=>"SDFs"}, "list_id"=>"1", "commit"=>"Add"}
  User Load (0.3ms)  SELECT "users".* FROM "users" WHERE "users"."remember_token" = '5AXS8-7-YRyLyGDKYHIZRg' LIMIT 1
  List Load (0.2ms)  SELECT "lists".* FROM "lists" WHERE "lists"."user_id" = 1 AND "lists"."id" = ? LIMIT 1  [["id", "1"]]
   (0.1ms)  begin transaction
  SQL (0.7ms)  INSERT INTO "items" ("created_at", "image", "link", "title", "updated_at") VALUES (?, ?, ?, ?, ?)  [["created_at", Sat, 16 Feb 2013 20:57:10 UTC +00:00], ["image", "profile.jpg"], ["link", "SDFs"], ["title", "YES"], ["updated_at", Sat, 16 Feb 2013 20:57:10 UTC +00:00]]
   (2.7ms)  commit transaction
Redirected to http://localhost:3000/items/1
Completed 302 Found in 830ms (ActiveRecord: 4.0ms)
4

3 に答える 3

0

最初に要約してみましょう。ある特定のアイテムに関連するウィッシュを含むリストを持つユーザーがいます。

それでは、最初に次のコード行を見てみましょう。

@item.lists.first.name

つまり、railsがアイテムを受け取り、このアイテムを含むすべてのリストにウィッシュを通過し、最初のリストを受け取り、リスト名を探します。表示される問題は、アイテムがウィッシュを介してどのリストにも関連付けられていない場合に発生します(たとえば、アイテムのcreateメソッドが新しいアイテムをウィッシュに接続しないため、リストへの接続も失われるため):アイテムには関係がありませんリストに追加すると、の結果@item.listsは空のリストになります。そしてfirst、空のリストの要素は何も(nil)ではなく、もちろんnil名前もありません。

結果は、あなたが見るものです:

undefined method 'name' for nil:NilClass

これを修正する1つの方法try()は、関連するメソッドが使用可能な場合にのみ実行するを使用することです。

@item.lists.first.try(:name)

あなたが話していたもう一つの問題は、ユーザーからアイテムを作成するときにウィッシュが生成されないことです。私はあなたが明示的に願いを構築する必要があると思います。100%確信はありませんが:through、モデルで-relationsを宣言することはクエリにのみ使用され、生成/構築には使用されないと思います。

アイテムコントローラーで次のようなものを試してください(最初にウィッシュを明示的に作成し、その後、ウィッシュのアイテムを作成するという考え方です)。

@wish = @list.wishes.build()
@wish.save
@item = @wish.item.build(params[:item])
于 2013-02-16T22:18:50.027 に答える
0

これはbuildhas_many :through. を含めるには、 itemsonの関連付けを変更する必要があります。Listinverse_of

class List < ActiveRecord::Base
  belongs_to :user
  has_many :wishes, dependent: :destroy
  has_many :items, through: :wishes, inverse_of: :wishes
end

Wish次に、接続オブジェクトを適切に構築する必要があります。

詳細については、この関連する問題を参照してください: https://github.com/rails/rails/pull/7661#issuecomment-8614206

于 2013-02-17T04:21:06.687 に答える
0

多くのグーグル検索と試行錯誤の後、Wish を明示的にビルドする必要があることがわかりました。create アクションは最終的に次のようになります。

def create
    @list = current_user.lists.find(params[:list_id])
    @item = Item.create!(params[:item])
    @item.wishes.build(list_id: @list.id)
    if @item.save
      flash[:success] = "Item created!"
      redirect_to @item
    else
      render 'new'
    end
end
于 2013-02-22T10:30:00.493 に答える