2015-12-27 31 views
0

我有一个用户和链接MVC。我将它们列在下面。基本上,当我创建一个新链接时,我希望它与我的用户绑定,然后在我的显示页面上显示带有引号的用户电子邮件,但是当我进行身份验证时,我仍然得到一个零值用户:用户和链接关联困难

  1. 用户和链路ASSOCATION
  2. 允许在我的强烈参数:user_id
  3. 已要求用户一个的before_filter作出新的请求
  4. 当记录有USER_ID我的链接模式

如果您看看我的show.html.erb和行<%= @link.user.try(:email) %>,这是发布该链接的用户电子邮件应该出现的位置,但它们都以零值表示。

我现在有点迷路,为什么我不能得到这个工作,任何帮助将非常感激!

型号:

class User < ActiveRecord::Base 
    has_many :links 
    acts_as_voter 
    devise :database_authenticatable, :registerable, 
    :recoverable, :rememberable, :trackable, :validatable 
end 

class Link < ActiveRecord::Base 
    belongs_to :user 
    acts_as_votable 
    attr_accessor :avatar 
    mount_uploader :avatar, AvatarUploader 
end 

控制器:

class LinksController < ApplicationController 
    before_filter :authenticate_user!, except: [:index, :show] 

    def index 
    @links = Link.all 
    end 

    def show 
    @link = Link.find(params[:id]) 
    end 

    def new 
    @link = Link.new 
    end 

    def edit 
    end 

    def create 
    @link = Link.new(link_params) 

    if @link.save 
     redirect_to root_path 
    else 
     render 'new' 
    end 
    end 

    private 

    def link_params 
    params.require(:link).permit(:title, :url, :avatar, :user_id) 
    end 
end 

show.html.erb:

<p id="notice"><%= notice %></p> 

<p> 
    <strong>Author:</strong> 
    <%= @link.title %> 
</p> 

<p> 
    <strong>Quote:</strong> 
    <%= @link.url %> 
</p> 

<small class="author">Submitted <%= time_ago_in_words(@link.created_at) %> ago by <%= @link.user.try(:email) %></small> 

模式:

create_table "links", force: :cascade do |t| 
    t.string "title" 
    t.string "url" 
    t.datetime "created_at",      null: false 
    t.datetime "updated_at",      null: false 
    t.integer "user_id" 
    t.integer "cached_votes_total", default: 0 
    t.integer "cached_votes_score", default: 0 
    t.integer "cached_votes_up", default: 0 
    t.integer "cached_votes_down", default: 0 
    t.string "avatar" 
    end 

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 
    end 

回答

1

它听起来不像user_id曾经设置过。碰巧,你可能不想通过参数设置它(因为这些可以由用户操纵)。

相反,更换

@link = Link.new(link_params) 

随着

@link = current_user.links.build(link_params) 

如果链接始终有一个用户,我也将标志着user_id列不为空,而不是乱抛垃圾我的电话应用try(和我一般宁愿try!try

+0

谢谢你的回答,协会现在正常工作。出于我自己的好奇心,你为什么认为link_params没有设置用户?至于你最后的评论,我应该运行一个迁移改变user_id为null:我的链接表中的false? – Jbur43

+0

因为你的表单很可能没有user_id字段(或者它是空白的)。我会编写一个迁移来更改user_id的nullness,但这取决于您(并且您需要删除任何具有空user_id的行) –

+0

感谢您花时间解释这一点,我非常感谢。 – Jbur43

0

1.据我所知,逻辑是你只能在登录后创建链接。用户只能为他/她创建链接(只有登录的用户可以是他创建的链接的所有者)。在这种情况下,你不应该暴露在USER_ID形式,而是将其添加在创建行动:

def create 
    @link = Link.new(link_params) 

    if @link.save 
     current_user.links << @link 
     redirect_to root_path 
    else 
     render 'new' 
    end 
    end 

2.Also,如果你不允许孤儿链接(没有用户作为所有者),那么我建议不使用user.try(:email)而是@link.user.email

  • 如果通过@link访问用户对象,那么你可以在表演的动作,以节省一些DB预装它查询

    def show 
    @link = Link.includes(:user).find(params[:id]) 
    end 
    
  • 进行这些更改并重试。此外,电子邮件要求用户如果使用的是默认色器件配置,使.try(:email)返回nil可能意味着user对象没有找到,这意味着关联设置不正确(我的版本可能会解决这个问题)