【问题标题】:Rails Associations - Values are correct, but association is nilRails 关联 - 值正确,但关联为零
【发布时间】:2015-10-16 23:31:17
【问题描述】:

我整个下午都在做这个,我已经很接近了,但是我的大脑只是跳过了一些简单的事情,但我看不到它。

在这个网站上,用户可以创建和加入俱乐部。当用户加入俱乐部时,他们作为俱乐部成员加入。俱乐部会员可以在俱乐部发帖。出于某种原因,我无法让我的俱乐部成员发布协会正常工作。该值正在使用正确的 id 填充,但是当我在控制台中检查关联时,我得到了 nil。我的目标是能够获得发布帖子的俱乐部成员的用户名。

用户模型

has_many :club_memberships, :class_name => 'ClubMembership', :foreign_key => :member_id, :primary_key => :id 
has_many :clubs, :through => :club_memberships 

俱乐部模式

has_many :club_memberships
has_many :members, :through => :club_memberships
has_many :posts

俱乐部会员模式

belongs_to :club 
belongs_to :member, :class_name => "User", :foreign_key => :member_id, :primary_key => :id 
has_many :posts

后模型

belongs_to :club
belongs_to :club_membership

相关路线

resources :clubs do
    resources :posts
end
  resources :club_memberships, :only => [:index, :create, :destroy] 

帖子控制器

class PostsController < ApplicationController
  before_action :set_post, only: [:show, :edit, :update, :destroy]
  before_action :set_club
  before_action :set_membership_id

  def new
    @post = Post.new
  end

  def show
    @posts = Post.find(params[:id])
  end

  def create
    @post = Post.new(post_params)
    @post.member_id = @club_membership.id
    @post.club_id = @club.id

    if @post.save
      redirect_to @club
    else
      render 'new'
    end
  end


  private
    def set_post
      @post = Post.find(params[:id])
    end

    def set_club
      @club = Club.find(params[:club_id])
    end

    def set_membership_id
      @club_membership = @club.club_memberships.find_by(member_id: current_user)
    end

    def post_params
      params.require(:post).permit(:title, :postcontent)
    end
end

帖子是通过俱乐部页面上的 new_club_post_path(@club) link_to 创建的。帖子创建正确,值正确。

最近发布的控制台结果

> @post = Post.find(7)
  Post Load (0.2ms)  SELECT  `posts`.* FROM `posts` WHERE `posts`.`id` = 7 LIMIT 1
 => #<Post id: 7, member_id: 29, club_id: 22, title: "fdsafsadfas", postcontent: "fsdafsadfsadfsadfasdf", created_at: "2015-10-16 22:39:28", updated_at: "2015-10-16 22:39:28"> 

调用@post.club 返回真

> @post.club
  Club Load (0.2ms)  SELECT  `clubs`.* FROM `clubs` WHERE `clubs`.`id` = 22 LIMIT 1
 => #<Club id: 22, club_name: "new test club", club_type: "Movies", created_at: "2015-10-16 22:34:51", updated_at: "2015-10-16 22:34:51"> 

但是当我尝试@post.club_membership 时,结果为 nil,我不知道为什么会这样。

> @post.club_membership
 => nil 

如果我尝试为@club 设置特定值,我可以调用@club.club_memberships,所以我认为该关联运行良好。我只是在从 post 到 club_membership 时遇到问题。我希望调用像这样的@post.club_membership.username 并让值返回帖子的关联用户名。如果我现在打电话,我会得到 ​​p>

NoMethodError: undefined method `username' for nil:NilClass

谢谢!

编辑—— 这是 post 表的创建迁移。

class CreatePosts < ActiveRecord::Migration
  def change
    create_table :posts do |t|
      t.integer :member_id
      t.integer :club_id
      t.string :title
      t.text :postcontent

      t.timestamps null: false
    end
  end
end

更新答案 感谢这个网站上很棒的用户,我能够弄清楚这一点。

我的帖子模型应该有这个作为关联:

belongs_to :club_membership, :class_name => 'ClubMembership', :foreign_key => :member_id, :primary_key => :id 

这让我可以致电@post.club_membership.member.username 来获取要显示的海报的用户名。

【问题讨论】:

  • 你有一个 post.member_id 方法,看起来这应该是一个 ClubMembership,但你没有在 post 模型中明确说明外键。看起来 member_id 指的是俱乐部会员模型上的用户。
  • 我刚刚更新了迁移后的内容。老实说,我对外键感到非常困惑,所以我尝试将它们排除在外,除非我找到了其他人以类似方式使用它的东西并且我能弄明白。这对我来说可能是一种糟糕的学习方式,但我会做到的。
  • 在这种情况下 - 我建议您将外键与表相匹配。外键只是它们关联的类的 ID。 Belongs_to 是唯一具有外键的。如果列与类同名并以 _id 为后缀,则不需要显式外键
  • 谢谢!你的回复以及@smathy 真的帮助我弄清楚了这一点。

标签: ruby-on-rails ruby-on-rails-4 activerecord associations belongs-to


【解决方案1】:

正如您在(优秀)问题中所展示的,您的帖子具有以下属性(以及时间戳和 id):

member_id: 29
club_id: 22
title: "fdsafsadfas"
postcontent: "fsdafsadfsadfsadfasdf"

您的Post 模型具有以下关联:

belongs_to :club
belongs_to :club_membership

其中第一个将查找名为club_id 的属性(并找到它),第二个将查找名为club_membership_id 的属性但未找到。所以关联方法永远不会起作用。

从您的代码和问题来看,我怀疑这就是您需要有人指出的全部内容,但如果您不清楚您的问题,请告诉我。

【讨论】:

  • 非常感谢您引导我朝着正确的方向前进,而不是仅仅给我答案! :) 我对我来说有点挑战,因为我对 Rails 还是很陌生,但我喜欢这个谜题,找到解决方案的感觉真的很好。我用未来用户的解决方案更新了我的问题。
猜你喜欢
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多