用户返回零。 nil的未定义方法`username':NilClass

时间:2013-12-11 00:27:43

标签: ruby-on-rails ruby model controller ruby-on-rails-4

以下是我收到的错误: error nillclass username things

这是文件的要点(你们中的一些人可能会发现这更容易阅读):

https://gist.github.com/drichards2013/7902811

这是index.html.erb:

<%= render 'pages/home' if !user_signed_in? %>

<div id="things" class="transitions-enabled">
  <% @things.each do |thing| %>
    <div class='panel panel default'>
    <div class="box">
      <%= link_to image_tag(thing.image.url(:medium)), thing %>
      <div class='panel-body'>

      <% if thing.link.blank? %>
      <strong><%= thing.title %></strong>
      <% else %>
      <strong><%= link_to thing.title, "http://#{thing.link}"%></strong>
      <% end %>

      <p><%= thing.description %></p>
      By <%= link_to thing.user.username, user_path(thing.user) %>

      <% if thing.user == current_user %>
        <%= link_to edit_thing_path(thing) do %>
        <span class='glyphicon glyphicon-edit'></span>
      <% end %>
      <%= link_to thing_path(thing), method: :delete, data: { confirm: 'Are you sure?' } do %>
        <span class='glyphicon glyphicon-trash'></span>
      <% end %>
      </div>
      <% end %>
      </div>
    </div>
  <% end %>
</div>


<%= will_paginate @posts, renderer: BootstrapPagination::Rails, class: 'pull-left' %>

这是thing.rb:

class Thing < ActiveRecord::Base
  belongs_to :user

  default_scope -> { order('created_at DESC') }

  has_attached_file :image, :styles => { :large => '500x500>', :medium => '300x300>', :thumb => '100x100>' }

  validates :image, presence: true
  validates :title, presence: true, length: { minimum: 5, maximum: 50 }

  # Returns microposts from the users being followed by the given user.
  def self.from_users_followed_by(user)
    followed_user_ids = "SELECT followed_id FROM relationships
                         WHERE follower_id = :user_id"
    where("user_id IN (#{followed_user_ids}) OR user_id = :user_id",
          user_id: user.id)
  end

end


class ThingsController < ApplicationController
  before_action :set_thing, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]

  # GET /things
  # GET /things.json
  def index
    @things = Thing.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 50)
  end

  # GET /things/1
  # GET /things/1.json
  def show
  end

  # GET /things/new
  def new
    @thing = current_user.things.build
  end

  # GET /things/1/edit
  def edit
  end

  # POST /things
  # POST /things.json
  def create
    @thing = current_user.things.build(thing_params)

    respond_to do |format|
      if @thing.save
        format.html { redirect_to @thing, notice: 'Thing was successfully created.' }
        format.json { render action: 'show', status: :created, location: @thing }
      else
        format.html { render action: 'new' }
        format.json { render json: @thing.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /things/1
  # PATCH/PUT /things/1.json
  def update
    respond_to do |format|
      if @thing.update(thing_params)
        format.html { redirect_to @thing, notice: 'Thing was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @thing.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /things/1
  # DELETE /things/1.json
  def destroy
    @thing.destroy
    respond_to do |format|
      format.html { redirect_to things_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_thing
      @thing = Thing.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def thing_params
      params.require(:thing).permit(:title, :description, :image, :link)
    end
  end

这是things_controller.rb:

class ThingsController < ApplicationController
  before_action :set_thing, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!, except: [:index, :show]

  # GET /things
  # GET /things.json
  def index
    @things = Thing.all.order("created_at DESC").paginate(:page => params[:page], :per_page => 50)
  end

  # GET /things/1
  # GET /things/1.json
  def show
  end

  # GET /things/new
  def new
    @thing = current_user.things.build
  end

  # GET /things/1/edit
  def edit
  end

  # POST /things
  # POST /things.json
  def create
    @thing = current_user.things.build(thing_params)

    respond_to do |format|
      if @thing.save
        format.html { redirect_to @thing, notice: 'Thing was successfully created.' }
        format.json { render action: 'show', status: :created, location: @thing }
      else
        format.html { render action: 'new' }
        format.json { render json: @thing.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /things/1
  # PATCH/PUT /things/1.json
  def update
    respond_to do |format|
      if @thing.update(thing_params)
        format.html { redirect_to @thing, notice: 'Thing was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @thing.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /things/1
  # DELETE /things/1.json
  def destroy
    @thing.destroy
    respond_to do |format|
      format.html { redirect_to things_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_thing
      @thing = Thing.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def thing_params
      params.require(:thing).permit(:title, :description, :image, :link)
    end
  end

这是user.rb:

class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable, #:recoverable,
          :rememberable, :trackable, :validatable

  has_many :things

  validates :name, presence: true, length: { minimum: 2, maximum: 20}
  validates :username, presence: true, length: { minimum: 2, maximum: 20}
  validates :username, uniqueness: true
  validates :email, presence: true
  validates :email, uniqueness: true



  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" , :nav => "25x25"}

  extend FriendlyId
  friendly_id :username

  def show

  end

  #follow features
  has_many :followed_users, through: :relationships, source: :followed
  has_many :relationships, foreign_key: "follower_id", dependent: :destroy
  has_many :followed_users, through: :relationships, source: :followed

  def following?(other_user)
    relationships.find_by(followed_id: other_user.id)
  end

  def follow!(other_user)
    relationships.create!(followed_id: other_user.id)
  end

  def unfollow!(other_user)
    relationships.find_by(followed_id: other_user.id).destroy!
  end

  def feed
    Thing.from_users_followed_by(self)
  end

  has_many :reverse_relationships, foreign_key: "followed_id",
                                   class_name:  "Relationship",
                                   dependent:   :destroy
  has_many :followers, through: :reverse_relationships, source: :follower


end

这是users_controller.rb:

class UsersController < ApplicationController
  def show
    @user = User.find_by_username(params[:id])
  end

  def user_params
      params.require(:user).permit(:avatar)
  end


  def following
      @title = "Following"
      @user = User.find_by_username(params[:id])
      @users = @user.followed_users.paginate(page: params[:page])
      render 'show_follow'
    end

    def followers
      @title = "Followers"
      @user = User.find_by_username(params[:id])
      @users = @user.followers.paginate(page: params[:page])
      render 'show_follow'
    end
end

我尝试了什么

我去了控制台,做了thing = Thing.last,然后尝试拨打thing.user,然后返回nil。所以看来user_id没有保存。我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

这就是“尝试”方法是你的朋友。

您正在尝试从用户那里获取“用户名”值,但这个值已经丢失。

如果你要写下你的行:

thing.user.try(:username)

然后它不会崩溃,如果用户存在,它将获取用户名。

您的用户未保存,因为未设置您的一对多关系。您可能希望将user_id添加到您的thing表中。

答案 1 :(得分:1)

通过将:user_id添加到my things controller中的thing_params方法来修复。

def thing_params
  params.require(:thing).permit(:title, :description, :image, :link, :user_id)
end