2016-02-01 2 views
1

Я новичок в Rails и создаю приложение todo.Отображение пустого элемента из вложенного ресурса

По какой-либо причине пустой экземпляр Item отображается во всех списках по умолчанию. Item.count возвращает 0, но <%= render @list.items %> всегда имеет один экземпляр _item.html.erb.

У меня есть @list, назначенный на List.find(params[:id]) в способе отображения контроллера контроллера, и я вызываю <%= render @list.items %> в его представлении.

У меня есть эта связь в _item.html.erb

<%= link_to "Delete", [item.list, item], 
    method: :delete, 
    data: { confirm: "Are you sure?" } 
%> 

и он будет отображать ссылку удалить, но ссылку на lists/*/items (в отличие от list/*/items/*) в пустой пункт, который дает ошибку маршрутизации. Тем не менее, ссылка работает отлично на реальных элементах.

Контроллеры:

lists_controller.rb:

class ListsController < ApplicationController 
    before_action :set_list, only: [:show, :edit, :update, :destroy] 

    def index 
    @lists = policy_scope(List).where(author: current_user) 
    end 

    def show 
    @item = @list.items.build 
    end 

    def new 
    @list = List.new 
    authorize @list 
    end 

    def create 
    @list = List.new(list_params) 
    @list.author = current_user 
    authorize @list 

    if @list.save 
     flash[:notice] = "Your list was created." 
     redirect_to @list 
    else 
     flash[:error] = "Your list was not created." 
     render "new" 
    end 
    end 

    def edit 
    end 

    def update 
    if @list.update(list_params) 
     flash[:notice] = "Your list was updated." 
     redirect_to @list 
    else 
     flash[:error] = "Your list was not updated." 
     render "edit" 
    end 
    end 

    def destroy 
    if @list.destroy 
     flash[:notice] = "Your list was deleted." 
     redirect_to root_path 
    else 
     flash[:error] = "Your list was not deleted." 
     redirect_to @list 
    end 
    end 

    private 

    def list_params 
    params.require(:list).permit(:title, :description, :author_id) 
    end 

    def set_list 
     @list = List.find(params[:id]) 
     authorize @list 
    end 
end 

items_controller.rb:

class ItemsController < ApplicationController 
    before_action :set_list 

    def create 
    @item = @list.items.create(item_params) 
    authorize @item 

    if @item.save 
     flash[:notice] = "Your item was added." 
     redirect_to @list 
    else 
     flash.now[:error] = "Your item was not added." 
    end 
    end 

    def destroy 
    @item = @list.items.find(params[:id]) 
    authorize @item 

    if @item.destroy 
     flash[:notice] = "Your item was deleted." 
     redirect_to @list 
    else 
     flash.now[:error] = "Your item was not deleted." 
    end 
    end 

    private 

    def item_params 
    params.require(:item).permit(:name, :list_id) 
    end 

    def set_list 
    @list = List.find(params[:list_id]) 
    end 
end 

Модели:

list.rb:

class List < ActiveRecord::Base 
    validates :title, presence: true 
    validates :description, presence: true 

    belongs_to :author, class_name: "User" 

    has_many :items, dependent: :destroy 
end 

item.rb:

class Item < ActiveRecord::Base 
    validates :name, presence: true 

    belongs_to :list 
end 

Маршруты:

Rails.application.routes.draw do 
    root "lists#index" 

    resources :lists do 
    resources :items 
    end 

    devise_for :users 
end 

Ссылка миграции:

class AddListsToItems < ActiveRecord::Migration 
    def change 
    add_reference :items, :list, index: true, foreign_key: true 
    end 
end 

ответ

0

@item = @list.items.build ваша проблема.

Проблема заключается в том, что здание вложенный элемент всегда будет давать «пустой» элемент, особенно если он вложен.

Хотя вы можете использовать код в new действия безнаказанно, используя в show будет в основном просто создать пустой объект, который вы должны бороться.

-

Если вы хотите создать newitem объект при просмотре @list, вы будете лучше здания/вызова на лету (как вы делаете уже):

<%= form_for [@list, @list.items.new] ... 
0

попробовать

<%= render 'item' %> 

и на свой _item.html.erb (который оказывается), можно использовать следующий код:

<%= @list.items %> 
+0

Это помещает это в элемент 'ul':' # '. Предполагая, что вы хотите, чтобы я разместил _item.html.erb в представлениях/списках. –

+0

Yup, вам нужно поместить визуализированный шаблон для просмотра папки, в которой вы ее назвали. – Lymuel

+0

Я сделал то, и эта строка была отображена на странице. Однако шестнадцатеричная часть изменяется при каждом обновлении. –

1

Проблема была вызвана тем, как я прошел переменный экземпляр в форму.

Эта строка в ListsController создает новый элемент на каждой странице обновления.

def show 
    @item = @list.items.build 
end 

Я удалил это задание, а также его переход к форме.

<%= render "items/form", list: @list, item: @item %> становится <%= render "items/form", list: @list %>

simple_form_for([list, item] становится simple_form_for([@list, @list.items.build]

Смежные вопросы