我需要帮助,有一些我还没有理解的东西。 我想显示已发布“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
当我搜索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 ....
答案 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