【问题标题】:Many-to-Many relationship only works one way Rails / Activerecord / devise多对多关系仅以一种方式工作 Rails / Activerecord / devise
【发布时间】:2014-11-20 01:52:16
【问题描述】:

我有一个多对多的关系用户到列表 用户模型是用 devise 创建的。

由于某种原因,我无法访问任何用户的 .lists。为 nil:NilClass 返回未定义的方法 `to_sym'。

在做了一些挖掘之后,我很确定我发现了问题 _reflect_on_associationactiverecord (4.1.6) lib/active_record/reflection.rb

def _reflect_on_association(association) #:nodoc:
        _reflections[association.to_sym]
      end

association 以 nil 形式传入。

以前有人遇到过这个问题吗?

在 Rails 控制台中测试关系

[15] pry(main)> testuser = User.new
=> #<User id: nil, email: "", encrypted_password: "", reset_password_token: nil,         reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at:    nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil,   updated_at: nil, provider: nil, uid: nil, name: nil, image: nil>
[16] pry(main)> testlist = List.new
=> #<List id: nil, name: nil, created_at: nil, updated_at: nil>
[17] pry(main)> testlist.users
=> []
[18] pry(main)> testuser.lists
NoMethodError: undefined method `to_sym' for nil:NilClass
from /Users/user/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.6/lib/active_record/reflection.rb:100:in `_reflect_on_association'

[19] pry(main)> testlist.users << testuser
=> [#<User id: nil, email: "", encrypted_password: "", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, sign_in_count: 0, current_sign_in_at: nil, last_sign_in_at: nil, current_sign_in_ip: nil, last_sign_in_ip: nil, created_at: nil, updated_at: nil, provider: nil, uid: nil, name: nil, image: nil>]


[22] pry(main)> testuser.lists << testlist
NoMethodError: undefined method `to_sym' for nil:NilClass
from /Users/user/.rvm/gems/ruby-2.1.2/gems/activerecord-4.1.6/lib/active_record/reflection.rb:100:in `_reflect_on_association'

型号

列表模型

class List < ActiveRecord::Base
    has_many :notes
    has_many :list_users
    has_many :users, through: :list_users

end

用户模型(设计)

    class User < ActiveRecord::Base
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
  :recoverable, :rememberable, :trackable, :validatable
  devise :omniauthable, :omniauth_providers => [:facebook, :twitter]

  has_many :list_users
  has_many :lists, through: :list_users


  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
        user.email = auth.info.email
        user.password = Devise.friendly_token[0,20]
            user.name = auth.info.name   # assuming the user model has a name
            user.image = auth.info.image # assuming the user model has an image
        end
    end

    def self.new_with_session(params, session)
        super.tap do |user|
            if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
                user.email = data["email"] if user.email.blank?
            end
        end
    end
end

ListUser 模型(连接表)

class ListUser < ActiveRecord::Base
    belongs_to :note
    belongs_to :user
end

架构

create_table "list_users", force: true do |t|
    t.integer  "list_id"
    t.integer  "user_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "lists", force: true do |t|
    t.string   "name"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "users", force: true 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.inet     "current_sign_in_ip"
    t.inet     "last_sign_in_ip"
    t.datetime "created_at"
    t.datetime "updated_at"
    t.string   "provider"
    t.string   "uid"
    t.string   "name"
    t.string   "image"
  end

  add_index "users", ["email"], name: "index_users_on_email", unique: true, using: :btree
  add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true, using: :btree

end

【问题讨论】:

    标签: ruby-on-rails activerecord devise many-to-many


    【解决方案1】:

    很晚了,但我自己也遇到过同样的问题。

    似乎后面的 rails 不再详细说明关联问题的原因;尝试更改 ListUser 模型中的 belongs_to 关联名称。

    我猜应该是这样的:

    class ListUser < ActiveRecord::Base
        belongs_to :list
        belongs_to :user
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-06
      • 2016-09-03
      • 1970-01-01
      • 2019-06-17
      • 2022-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多