当前位置: 动力学知识库 > 问答 > 编程问答 >

ruby on rails - User and Link association difficulties

问题描述:

I have a user and link MVC. I listed them below. Essentially when I create a new link I want it to be tied to my user and then display the users email with the quote on my show page, but I continue to get a nil value for a user when I authenticate even though I have:

  1. a user and link assocation
  2. permitted :user_id in my strong parameters
  3. have a before_filter that requires a user be logged in when making a new request
  4. have a user_id in my link schema

If you take a look at my show.html.erb and the line <%= @link.user.try(:email) %>, this is where the users email should appear that posted the link, but they all come across as nil values.

I am a little lost right now as to why I can't get this to work, any help would be very appreciated!

Models:

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

Controllers:

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>

Schema:

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

网友答案:

It doesn't sound like user_id is ever set. As it happens, you probably don't want to set it via the params anyway (since these can be manipulated by the user).

Instead, replace

 @link = Link.new(link_params)

With

 @link = current_user.links.build(link_params)

If links always have a user, I would also mark the user_id column as not null instead of littering my app with calls to try (And I would in general prefer try! to try)

网友答案:

1.As I understand, the logic is that you can only create links once your logged in. And a user can create links only for him/her (only user logged in can be the owner of links he created). In that case you should not expose user_id in form but instead add it in the 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.Also, if you don't allow orphan links(with no user as the owner), then I suggest not using user.try(:email) but instead @link.user.email

  1. If you are accessing user object through @link then you could preload it in the show action to save some DB queries

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

Make these changes and try again. Also, email is required for a user if you are using default devise configuration, so .try(:email) returning nil might mean that the user object is not found, which means that the associations are not properly set (my version might fix that)

分享给朋友:
您可能感兴趣的文章:
随机阅读: