2016-12-31 2 views
0

Я работал с вложенными атрибутами, все казалось прекрасным, пока я не отправил свою информацию, и я получил эту ошибку. Он говорит, что это в моем EventsController файл:undefined method `events 'for nil: NilClass

class EventsController < ApplicationController 

    def new 
     @event = Event.new 
     @event.songs.build 
    end 

    def index 
     @songs = Song.all 
    end 

    def show 
     @event = Event.find(params[:id]) 
     @songs = @event.songs.paginate(page: params[:page]) 
    end 

    def create 
     @event = current_user.events.build(event_params) 
     if @event.save 
      flash[:success] = "Event Created!" 
      redirect_to user_path(@event.user) 
     else 
      render 'welcome#index' 
     end 
    end 

    def destroy 
    end 

    private 

     def event_params 
     params.require(:event).permit(:name, :partycode, song_attributes: [:event_id, :artist, :title, :genre, :partycode]) 
     end 
end 

Вот мой файл new.html.erb в моих песнях просмотра (обрабатывает представление песни на основе выбранного события)

<br> 
<br> 
<div class ="container"> 
    <div class="jumbotron"> 
    <%= form_for Event.new do |f| %> 
    <h3>Enter a song:</h3> 
    <%= f.fields_for :songs, Song.new do |song_form| %> 

     <%= song_form.collection_select(:event_id, Event.all, :id, :name) %> 
     <%= song_form.text_field :artist, placeholder: "Artist" %> 
     <%= song_form.text_field :title, placeholder: "Title" %> 
     <%= song_form.text_field :genre, placeholder: "Genre" %> 
    <% end %> 
    <%= link_to_add_fields "Add Song", f, :songs %> 
    <%= f.text_field :partycode %> 
    <%= f.submit "Submit", class: "btn btn-primary" %> 
    <% end %> 
    </div> 
</div> 

Метод link_to_add_fields определен в моем ApplicationHelper.rb файле:

module ApplicationHelper 
    def link_to_add_fields(name, f, association) 
    new_object = f.object.send(association).klass.new 
    id = new_object.object_id 
    fields = f.fields_for(association, new_object, child_index: id) do |builder| 
     render("songs_fields", f: builder) 
    end 
    link_to(name, '#', class: "add_fields", data: {id: id, fields: fields.gsub("\n", "")}) 
    end 
end 

current_user определяется в Session_helper.rb файле:

module SessionsHelper 

    # Logs in the given user. 
    def log_in(user) 
    session[:user_id] = user.id 
    end 

    def createEvent(event) 
    session[:event_id] = event.id 
    end 



    # Returns the current logged-in user (if any). 
    def current_user 
    @current_user ||= User.find_by(id: session[:user_id]) 
    end 
    # Returns true if the user is logged in, false otherwise. 
    def logged_in? 
    !current_user.nil? 
    end 

    def log_out 
    session.delete(:user_id) 
    @current_user = nil 
    end 

end 

Наконец, вот мой songs_fields файл, который генерирует поля только тогда, когда пользователь нажимает на ссылку, которая говорит «Добавить песни»

<fieldset> 
    <%= f.text_field :artist, placeholder: "Artist" %> 
    <%= f.text_field :title, placeholder: "Title" %> 
    <%= f.text_field :genre, placeholder: "Genre" %> 
</fieldset> 

Я чувствую, как будто это последняя часть, прежде чем я получаю все, что в моем приложении работать! Так что помощь в этом была бы огромной: D

+0

Ошибка объясняется '@event = current_user.events.build (event_params)' - 'current_user' является' nil' здесь. – 31piy

+0

Я понимаю эту ошибку, как бы исправить ее, потому что я не вхожу в систему с моим пользователем, когда добавляю песню? – Aaron

+0

Не знаю без дальнейших подробностей. Есть много способов. Проверьте конфигурацию. Вы используете devise, потому что 'current_user' относится к нему? Правильно ли передаются файлы cookie браузера? – 31piy

ответ

1

Вы ответили на свой вопрос ... если вы не вошли в систему, current_user будет nil, поэтому вы получите эту ошибку.

Вариант 1 (некрасиво): изменить вашу логику так current_user.events не дозвонились, если current_user равна нулю, а просто идти прямо к визуализации

Вариант 2 (лучше): использовать before_action заявление, чтобы заставить current_user быть установленным до того, как действие будет запущено. Зависит от того, что вы используете для проверки подлинности, но с Завещания он будет выглядеть следующим образом:

class EventsController < ApplicationController 
    before_action :authenticate_user! 

Я думаю, может быть:

class EventsController < ApplicationController 
    before_action :log_in(user) 

может сделать это для вас.