显示用户名?

时间:2016-09-16 17:34:04

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

我需要帮助,有一些我还没有理解的东西。 我想显示已发布“tuto”的用户的姓名......

这是tutos / index.html.slim 我一定是错的,或者我在其他地方遗漏了一些东西...... 有人可以解释一下吗?非常感谢

- @tutos.each do |tuto|
  .row
    .col-xs-4
      h6 = link_to tuto.title, tuto_path(tuto)
    .col-xs-4
      h6 = tuto.user.full_name

这是我的用户控制器:

class UsersController < ApplicationController
  before_action :authenticate_user!
  def show
      @user = User.find(current_user)
  end

  def index
    @user = User.all
  end

  #def full_name
    #first_name + last_name
  #end
  # Edited put this in the user model

  private
  def params_user
    params.require(:users).permit(:first_name, :last_name, :email, :id)
  end
end

以下是tutos控制器:

class TutosController < ApplicationController
  before_action :authenticate_user!
  #as suggested I added the line above
  before_action :set_tuto, only: [:show, :edit, :update, :destroy]


  def index
    @tutos = Tuto.all
  end

  def show
    @tuto = Tuto.find(params[:id])
  end


 def new
    @tuto = Tuto.new
    # as suggested I added the line below
    @user = current_user
  end


  def edit
  end

  def create
    @tuto = Tuto.new(tuto_params)

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


  def update
    respond_to do |format|
      if @tuto.update(tuto_params)
        format.html { redirect_to @tuto, notice: 'Tuto was successfully updated.' }
        format.json { render :show, status: :ok, location: @tuto }
      else
        format.html { render :edit }
        format.json { render json: @tuto.errors, status: :unprocessable_entity }
      end
    end
  end


  def destroy
    @tuto.destroy
    respond_to do |format|
      format.html { redirect_to tutos_url, notice: 'Tuto was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    def set_tuto
      @tuto = Tuto.find(params[:id])
    end

    def tuto_params
      params.require(:tuto).permit(:title, :content, :id, :user_id)
    end
end

架构:

ActiveRecord::Schema.define(version: 20160916141853) do

  create_table "tutos", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.string   "title"
    t.text     "content"
    t.integer  "user_id"
  end

  add_index "tutos", ["user_id"], name: "index_tutos_on_user_id"

  create_table "users", force: :cascade do |t|
    t.string   "email",                  default: "", null: false
    t.string   "encrypted_password",     default: "", null: false
    t.string   "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer  "sign_in_count",          default: 0,  null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.string   "current_sign_in_ip"
    t.string   "last_sign_in_ip"
    t.datetime "created_at",                          null: false
    t.datetime "updated_at",                          null: false
    t.string   "first_name"
    t.string   "last_name"
    t.boolean  "admin"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true

end

tuto模特:

class Tuto < ActiveRecord::Base
  belongs_to :user

end

用户模型:

class User < ActiveRecord::Base

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
  validates :first_name, presence: true
  validates :last_name,  presence: true
  has_many :tutos

  # moved this from the controller users (as suggested)
  def full_name
    first_name + last_name
  end


end

如果需要我的路线:

Rails.application.routes.draw do


  namespace :admin do
    get '', to: 'dashboard#index', as: '/'
    resources :tutos
    resources :users
    resources :dashboard
  end

  namespace :users do
    resources :tutos
  end

as :user do
  get '/register', to: 'devise/registrations#new', as: :register
  get '/login',    to: 'devise/sessions#new', as: :login
  get '/logout',   to: 'devise/sessions#destroy', as: :logout
end

devise_for :users, skip: [:sessions]

as :user do
  get     "/account"  => "users#show", as: :account
  get     "/login"    => "devise/sessions#new", as: :new_user_session
  post    "/login"    => "devise/sessions#create", as: :user_session
  delete  "/logout"   => "devise/sessions#destroy", as: :destroy_user_session
end

  resources :users
  resources :tutos

  root "home#landing"

编辑:

正如我建议的那样:

in tutos_controller.rb

  def new
    @tuto = Tuto.new
  end
像我这样的

hidden_​​field:

= simple_form_for @tuto do |f|
  - if @tuto.errors.any?
    #error_explanation
      h2 = "#{pluralize(@tuto.errors.count, "error")} prohibited this tuto from being saved:"
      ul
        - @tuto.errors.full_messages.each do |message|
          li = message
  = hidden_field_tag :user_id, current_user.id
  = f.input  :title
  = f.input  :content    
  = f.button :submit, "Save"

但我现在有这个错误:undefined method id' for nil:NilClass 当我创建tuto时,user_id始终为零....

我需要更多帮助:)

编辑(再次)

我有些奇怪...... 我试着用pry调试,我有这个: tutos_controller中的

  22: def create
 => 23:   binding.pry
    24:
    25:   @tuto = Tuto.new(tuto_params)
    26:
    27:   respond_to do |format|
    28:     if @tuto.save
    29:       format.html { redirect_to @tuto, notice: 'Tuto was successfully created.' }
    30:       format.json { render :show, status: :created, location: @tuto }
    31:     else
    32:       format.html { render :new }
    33:       format.json { render json: @tuto.errors, status: :unprocessable_entity }
    34:     end
    35:   end
    36: end

[1] pry(#<TutosController>)>
[1] pry(#<TutosController>)> params
=> {"utf8"=>"✓",
 "authenticity_token"=>"SkY9I70/ng+fwQr7HJ1oYzpKPI/kRnEsHxukIrAQ/kA+VOrS7TpXL0Ab6BW3O13sLZyrRWJpOxANLVIE/2wGVw==",
 "user_id"=>"1",
 "tuto"=>{"title"=>"A title", "content"=>"Some text"},
 "commit"=>"Save",
 "controller"=>"tutos",
 "action"=>"create"}

所以我可以注意到user_id: 1

BUT

当我搜索tuto时,在我的控制台中:

  Tuto Load (0.2ms)  SELECT  "tutos".* FROM "tutos"  ORDER BY "tutos"."id" DESC LIMIT 1
 => #<Tuto id: 16, created_at: "2016-09-17 08:59:09", updated_at: "2016-09-17 08:59:09", title: "A title", content: "Some text", user_id: nil>
2.3.1 :006 >

user_id是nil ....

3 个答案:

答案 0 :(得分:1)

很简单,方法 full_name 在控制器上,它需要在模型上。

你看到你正在使用它,但你有一个 tuto 对象引用他的用户模型,而full_name方法在控制器上,所以它是一个动作在控制器中不是用户模型的实例方法,这就是你需要的。

此外,您有 n + 1 问题,您需要在tutos控制器中包含您查询的用户:

def index
  @tutos = Tuto.all.includes(:user)
end

否则,每次显示用户名

时,每次tuto都会再次点击数据库

总而言之,只需将 full_name 方法从控制器 users_controller.rb 移至模型 user.rb ,同时检查{{ 3}}你是金色的。

好了,现在问题在于设计 gem。首先, current_user n+1 problem在回调中提供的帮助 authenticate_user!这通常应该在 application_controller.rb上,在调用回调之后,您可以访问 current_user 以及其他帮助程序,因此您不需要实例变量 @user ,因为 current_user 也将在视图上可用,您的问题似乎是回调没有被正确调用,它应该位于控制器层次结构的顶部。

答案 1 :(得分:0)

您需要定义full_name是什么。您可以在users.rb模型文件上编写一个方法,如下所示:

def full_name
  [last_name, first_name].join(", ")
end

对于first_name为&#34; John&#34;和{#1}}&#34;史密斯&#34;,它将返回&#34;史密斯,约翰&#34;。

EDIT 请参阅@aledustet的答案

答案 2 :(得分:0)

尝试以下。在user.rb

  def full_name
    if first_name.present? || last_name.present?
      "#{first_name} #{last_name}" 
    end
  end