2016-06-01 14 views
0

Ich habe diesen Fehler seit Stunden behoben und ich habe keine Ahnung, was ich falsch mache. Ich kann die Artikelsammlung einfach nicht für einen einzelnen Benutzer anzeigen lassen. Jeder Artikel gehört einem einzelnen Benutzer und jeder Benutzer hat viele Artikel. Momentan wird mein partielles Rendering nicht in der Showansicht des Benutzers angezeigt.Rails teilweise Vorlage mit Sammlung nicht richtig rendern

Wenn ich <%= render partial: "https://stackoverflow.com/users/item", collection: @user.items %> zu <%= render partial: "https://stackoverflow.com/users/item", collection: @items %> dann die Teilvorlage ändern wird gerendert, aber alle Elemente angezeigt, unabhängig davon, welcher Benutzer sie gehören. Nach dem Überprüfen der Datenbank wird jeder Eintrag ordnungsgemäß mit einem Fremdschlüssel user_id gespeichert, so dass das nicht das Problem ist.

Wie bekomme ich die richtigen Artikel für jeden Benutzer angezeigt? Ich habe schon mehrmals Teiltöne verwendet und habe alten und neuen Code miteinander verglichen. Ich kann den Unterschied nicht sehen und ich verliere meinen Verstand. Ich habe das allgemeine Internet, Stack Overflow, durchsucht und die Rails Guides for Layouts and Rendering überprüft. Ich habe den entsprechenden Code unten veröffentlicht und freue mich, noch etwas zu posten. Bitte helfen Sie!

views/users/_item.html.erb

<div> 
    <h4>ITEM: <%= item.title %></h4> 
    <p class="item"><%= item.cost %></p> 
</div> 

views/users/show.html.erb

<h1>Users#show</h1> 
<p>Find me in app/views/users/show.html.erb</p> 

<div><%= @user.first_name %></div> 

<h3>My List</h3> 
<%= render partial: "https://stackoverflow.com/users/item", collection: @user.items %> 

<span>ADD ITEM&nbsp;<%= link_to image_tag("Plus-50.png"), new_user_item_path(@user), class: "items-nved" %> </span> 

Controller/users_controller.rb

class UsersController < ApplicationController 

    before_action :set_user, only: [:show, :edit, :update, :destroy] 

    def index 
    @users = User.all 
    render :index 
    end 

    def show 
    @user = User.find(params[:id]) 
    # @item = Item.find(params[:id]) 
    @items = Item.all 
    @item = Item.new 
    @item.user_id = @user.id 
    end 

    def new 
    @user = User.new 
    end 

    def create 
    @user = User.new(user_params) 
    if @user.save 
     redirect_to new_session_path, method: :get 
    else 
     render "new" 
    end 
    end 

    def edit 
    end 

    def update 
    end 

    def destroy 
    end 

    private 
    def set_user 
    @user = User.find(params[:id]) 
    end 

    def user_params 
    params.require(:user).permit(:first_name, :last_name, :birthday, :city, :state, :email, :password, :password_confirmation) 
    end 
end 

Controller/items_controller.rb

class ItemsController < ApplicationController 

    include ItemsHelper 

    before_filter :require_login, only: [:new, :create, :update, :destroy] 

    def index 
    @current_user = current_user 
    @items = Item.all 
    end 

    def show 
    @user = current_user 
    @item = Item.find(params[:id]) 
    end 

    def new 
    @user = current_user 
    @item = Item.new 
    end 

    def create 
    @user = current_user 
    @item = Item.new(item_params) 
    @item.user_id = params[:user_id] # set user_id param from database to current_user id 
    @item.save 

    redirect_to user_item_path(@user, @item) 
    end 

    def edit 
    @user = current_user 
    @item = Item.find(params[:id]) 
    end 

    def update 
    @user = current_user 
    @item = Item.find(params[:id]) 
    @item.update(item_params) 
    redirect_to user_path(@user) 
    end 

    def destroy 
    @user = User.find params[:user_id] 
    @item = Item.find(params[:id]) 
    @item.destroy 
    redirect_to user_path(@user) 
    end 
end 

private 
    def user_params 
    params.require(:user).permit(:first_name, :last_name, :birthday, :city, :state, :email, :password, :password_confirmation) 
    end 

    def require_login 
    unless logged_in? 
     flash[:error] = "You must be logged in to access this section" 
     redirect_to new_login_url # halts request cycle 
    end 
    end 
+0

Sie können '@ user' einfach so 'collection: @ user' übergeben und in der Renderdatei' @ user.items' loopen. Versuchen Sie auch wie folgt '<% ​​= render partially:"/users/item ", lokal: {user_items: @ user.items}%>' – 7urkm3n

Antwort

1

Installieren Sie das byebug Juwel, entweder durch gem install byebug auf der Kommandozeile ausgeführt wird oder indem Sie in Ihrem Gemfile setzen byebug (dann laufen bundle install).

Put byebug kurz nach der @user Erklärung in Ihrem Userscontroller, wie folgt aus:

class UsersController < ApplicationController 

    before_action :set_user, only: [:show, :edit, :update, :destroy] 

    def index 
    @users = User.all 
    render :index 
    end 

    def show 
    @user = User.find(params[:id]) 
    byebug 

Dann starten Sie Ihren lokalen Server und gehen Sie die Ansicht Benutzer zeigen in Ihrem Browser. Die Seite wird nicht gerendert, denn wenn sie byebug erreicht, pausiert der Server.

Wenn dies der Fall ist, gehen Sie zurück zu Ihrem Terminal und schauen Sie sich Ihr Serverprotokoll an. Es wird auf Ihre Befehle warten. Geben Sie @user ein und drücken Sie die Eingabetaste. Was gibt es zurück?

Versuchen Sie auch @user.inspect.Gibt es ein Benutzerobjekt zurück?

Dann tun Sie @user.items. Was bringt das zurück? Wenn @user.items die erwartete Sammlung von Elementen zurückgibt, stimmt etwas nicht damit, wie Sie das an die Ansicht übergeben oder was Sie damit in der Ansicht tun.

Wenn @user.items keine Sammlung von Elementen zurückgibt, dann wird dies aus Ihrer Sicht nicht angezeigt! In diesem Fall hat es wahrscheinlich etwas mit Ihren ActiveRecord-Zuordnungen und/oder Ihren Migrationen zu tun.

Eine andere Möglichkeit ist, dass die aktuellen Elemente in Ihrer Datenbank möglicherweise erstellt wurden, bevor Sie die Zuordnungen hatten, so dass sie keine user_id haben. Sie können dies in Ihrer Rails-Konsole überprüfen. Stellen Sie sicher, dass Sie Elemente in Ihrer Datenbank haben, die dieselbe user_id wie Ihr current_user haben.

Eine andere gute Sache in Ihrer Rails-Konsole zu tun wäre, einen Benutzer, den Sie denken, hat einige Elemente zu einer Variablen zB user = User.first, und tun Sie dann user.items. Funktioniert es?

Ich empfehle auch einige RSpec Tests zu schreiben, zumindest auf Model-Ebene, um zu testen, dass die richtigen Assoziationen existieren. Die shoulda gem ist großartig dafür.

Kommentieren Sie hier mit Ihren Ergebnissen.

+0

Danke !! '@ user.inspect' gibt das korrekte Benutzerobjekt zurück. "@ User.items" gibt jedoch nicht die erwartete Sammlung von Elementen zurück, daher sind meine ActiveRecord-Verknüpfungen und/oder Migrationen das Problem! Seltsamerweise zeigt meine Rails-Konsole an, dass jedem Element der Fremdschlüssel user_id zugewiesen ist, und mein Benutzermodell hat 'has_many: items,: foreign_key => 'user_id',: primary_key => 'user_id'' und mein Artikelmodell' 'gehört zu: user,: foreign_key => 'user_id',: primary_key => 'user_id'', deshalb ist mir noch nicht klar, warum '@ user.items' keine Items-Collection zurückgibt. Ich denke, es ist wahrscheinlich meine Migrationen. –

+0

Versuchen Sie, diese Deklarationen in Ihren Modellen zu ändern: 'has_many: items' in Ihrem Benutzermodell und' gehört_to: user' in Ihrem Artikelmodell. Vor oder nach diesem Schritt müssen Sie jedoch einige frühere Migrationen rückgängig machen. Sie könnten dies folgendermaßen tun: http://edgeguides.rubyonrails.org/active_record_migrations.html#reverting-previous-migration (eleganter, aber etwas komplexer). Persönlich, nur weil ich faul bin, würde ich wahrscheinlich nur neue Migrationsdateien erstellen, um die Benutzertabelle und die Item-Tabelle vollständig zu löschen und dann Migrationen auszuführen, um sie mit den richtigen Assoziationen zu erstellen. – Andy

+0

Google 'drop_table' für Schienen-Migrationen, um Tabellen zu löschen. Sie könnten Datenbankprobleme bekommen, aber denken Sie daran, wenn Sie in einen richtigen Durcheinander geraten, können Sie einfach immer 'rake db: db: db: create db: migrate' ausführen, was Ihre Datenbank vollständig zerstört und neu erstellt, basierend auf Ihren aktuellen Migrationsdateien (Sie muss danach wieder Daten hinzufügen). Auch hier würde ich empfehlen, einige RSpec-Tests mit dem sophan-Juwel zu schreiben, weil ich _think_ (aber ich bin mir nicht sicher) nicht nur die Assoziationsdeklarationen in Ihren Modellen testen, sondern auch, dass Ihr db-Schema korrekt eingerichtet ist. – Andy

0

Try es so zu machen:

<%= render partial: "https://stackoverflow.com/users/item", locals: {user_items: @user.items} %> 

und Schleife es in _partial Datei:

<% user_items.each do |item| %> 
... 
<% end %> 
+0

Danke für den Vorschlag! Ich habe versucht, das partielle wie oben beschrieben zu rendern, und während die Vorlage statische Elemente darstellt, kann ich immer noch nicht die Artikeldaten anzeigen, geschweige denn die Artikeldaten, die an einen bestimmten Benutzer gebunden sind. –

0

Sie erwarten die Vorlage Rendering, um schlauer zu sein als es ist - es rendert alle Einzelteile, weil das ist, was in @items ist - es kennt Sie onl nicht Sie möchten Elemente für einen bestimmten Benutzer. Nichts falsch mit dem ursprünglichen Code

render partial: "https://stackoverflow.com/users/item", collection: @user.item 
+0

Genau, der ursprüngliche Code sollte funktionieren, aber es sollte auch Elemente für einen bestimmten Benutzer darstellen. Ich habe das gleiche Format zuvor verwendet und dies ist das erste Mal, dass ich ein Problem hatte. Aus meiner begrenzten früheren Erfahrung sollte <% = render partially: "/ users/item", collection: @ user.items%> 'Elemente anzeigen, die einem bestimmten Benutzer zugeordnet sind, seit die' .items' Methode auf '@ user' aufgerufen wurde sollte zu einem Array der zugeordneten Objektobjekte des Benutzers führen. In diesem Lernprogramm wird die Erläuterung [Anzeigen von Kommentaren für einen Artikel] (http://tutorials.jumpstartlab.com/projects/blogger.html#i2:-adding-comments) erläutert. –