用户和链接关联困难

时间:2015-12-27 14:36:56

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

我有一个用户并链接MVC。我在下面列出了它们。基本上,当我创建一个新链接时,我希望它与我的用户绑定,然后在我的显示页面上显示用户电子邮件和报价,但是当我进行身份验证时,即使我有以下情况,我仍然会为用户获取零值:< / p>

  1. 用户和链接关联
  2. 在我的强参数中允许:user_id
  3. 有一个before_filter,要求用户在发出新请求时登录
  4. 在我的链接架构中有一个user_id
  5. 如果您查看我的show.html.erb和行<%= @link.user.try(:email) %>,这就是用户发送链接的电子邮件的位置,但它们都是nil值。

    我现在有点失落,为什么我不能让这个工作,任何帮助都将非常感激!

    型号:

    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
    

2 个答案:

答案 0 :(得分:1)

听起来似乎没有设置user_id。碰巧的是,您可能不想通过params设置它(因为这些可以由用户操纵)。

相反,替换

 @link = Link.new(link_params)

使用

 @link = current_user.links.build(link_params)

如果链接始终有用户,我还会将user_id列标记为非空,而不是通过调用try来乱扔我的应用(我通常更喜欢try!try

答案 1 :(得分:0)

1.据我了解,逻辑是您只能在登录后创建链接。用户只能为他/她创建链接(只有登录的用户可以是他创建的链接的所有者)。在这种情况下,您不应在表单中公开user_id,而是将其添加到create action中:

 def create
    @link = Link.new(link_params)

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

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

  1. 如果您通过@link访问用户对象,则可以在show动作中预加载它以保存一些数据库查询

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