rails has_one直通关系不存在
rails has_one through relation does not exist
rails,postgres,设计。 Corporations 有一个 table 基地,我成功连接到她。 Objective:创建一个模型用户,它将绑定到公司,使公司能够以用户身份登录。我决定通过 has_one 使比率达到
user_corporation.rb:
class UserCorporation < ActiveRecord::Base
belongs_to :user
belongs_to :corporation
end
user.rb:
class User < ActiveRecord::Base
devise :database_authenticatable,
:rememberable,
:trackable,
:timeoutable,
:authentication_keys => [:login]
has_one :user_corporation
has_one :corporation, :through => :user_corporation
end
corporation.rb:
class Corporation < OtherBaseconfiguration
self.table_name = 'Corporations'
has_one :user_corporation
has_one :user, :through => :user_corporation
end
20160212185152_create_user_corporations.rb:
class CreateUserCorporations < ActiveRecord::Migration
def change
create_table :user_corporations do |t|
t.belongs_to :user, index: true
t.belongs_to :corporation, index: true
t.timestamps null: false
end
end
end
rake db: migrate
执行,table 被创建。在控制台中,尝试获取公司用户时,出现错误:
irb(main):006:0> @corpor.corporation
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "user_corporations" does not exist
LINE 5: WHERE a.attrelid = '"user_corporations"'::reg...
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"user_corporations"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:592:in `async_exec'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:592:in `block in exec_no_cache'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/abstract_adapter.rb:472:in `block in log'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/abstract_adapter.rb:466:in `log'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:592:in `exec_no_cache'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:584:in `execute_and_clear'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:160:in `exec_query'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:733:in `column_definitions'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql/schema_statements.rb:186:in `columns'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/schema_cache.rb:43:in `columns'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/schema_cache.rb:49:in `columns_hash'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/associations/association_scope.rb:85:in `column_for'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/associations/association_scope.rb:94:in `bind'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/associations/association_scope.rb:103:in `last_chain_scope'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/associations/association_scope.rb:139:in `add_constraints'
... 13 levels...
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/commands/console.rb:9:in `start'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:68:in `console'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/commands.rb:17:in `<top (required)>'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `block in require'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:240:in `load_dependency'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require'
from /home/marson/rails_project/infinity/bin/rails:9:in `<top (required)>'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `load'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `block in load'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:240:in `load_dependency'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `load'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
我做错了什么?
也许我遗漏了它,但如果您只需要公司和用户之间的 has_one 到 has_one,为什么要使用 UserCorporations 查找 table?
您的设计有缺陷,您试图以错误的方式使用 has_one,结果失败了。您想要以下设计之一:
一个
公司有很多用户
用户属于公司
(一个用户只能属于一个公司。一个公司可以有很多用户)。
B
Corporation 有很多 UserCorporations
用户有多个 UserCorporations
UsedCorporation属于用户
UserCorporation 属于公司
(这是多对多,所以一个用户可以属于多个军团,一个军团可以有多个用户)
C
公司属于用户
用户拥有多家公司
(一个用户连接多个军团,一个军团只能属于一个用户)
用 has_many :through
做
作为
(公司有很多用户用户 belongs_to
公司)
公司belongs_to
用户用户has_many
公司
(用户连接到多个公司,一个公司只能belong_to
一个用户)
macOS Big Sur 上的情况相同...
bundle list ...
- devise (4.8.0) ...
- pg (1.2.3) ...
- rails (6.1.3.2) ...
模型用户和用户规则(一个用户有一个规则)
class User < ApplicationRecord
has_one :user_rule
end
class DeviseCreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
## Database authenticatable
t.string :username, null: false, default: ""
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
....
end
end
end
class UserRule < ApplicationRecord
belongs_to :user
end
class CreateUserRules < ActiveRecord::Migration[6.1]
def change
create_table :user_rules do |t|
t.belongs_to :user, index: { unique: true }, foreign_key: true
....
end
end
end
config/database.yml
的内容
development:
<<: *default
database: <%= ENV['MY_DATABASE_NAME'] %>
host: <%= ENV['MY_DATABASE_HOST'] %>
port: <%= ENV['MY_DATABASE_PORT'] %>
username: <%= ENV['MY_DATABASE_USER'] %>
password: <%= ENV['MY_DATABASE_PASSWORD'] %>
清理数据库:
rake db:drop
rake db:create
rake db:migrate
转到控制台:
rails console
Running via Spring preloader in process 25238
Loading development environment (Rails 6.1.3.2)
2.7.2 :001 > User.new
=> #<User id: nil, username: "", email: "", ....>
2.7.2 :002 > UserRule.new
Traceback (most recent call last):
1: from (irb):2
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: relation "user_rules" does not exist)
LINE 8: WHERE a.attrelid = '"user_rules"'::regclass
如图所示,我的用户模型工作正常,但模型 UserRule 失败...
让我对数据库凭据而不是环境变量的设置进行硬编码...
文件config/database.yml:
development:
<<: *default
database: "app_development"
host: "localhost"
port: "5432"
username: "postgres"
password: "postgres"
重复...
rails console
Running via Spring preloader in process 25238
Loading development environment (Rails 6.1.3.2)
2.7.2 :001 > User.new
=> #<User id: nil, username: "", email: "", ....>
2.7.2 :002 > UserRule.new
=> #<UserRule id: nil, user_id: nil, ...>
哦惊喜!!!
问题不在于 Rails,是在使用环境值时 config/database.yml 中的数据库凭据...
当您在 macOS Big Sur、Intel 系列上工作时,将这些设置硬编码为解决方法。
与 Linux 一起工作就像一个魅力!!!
rails,postgres,设计。 Corporations 有一个 table 基地,我成功连接到她。 Objective:创建一个模型用户,它将绑定到公司,使公司能够以用户身份登录。我决定通过 has_one 使比率达到
user_corporation.rb:
class UserCorporation < ActiveRecord::Base
belongs_to :user
belongs_to :corporation
end
user.rb:
class User < ActiveRecord::Base
devise :database_authenticatable,
:rememberable,
:trackable,
:timeoutable,
:authentication_keys => [:login]
has_one :user_corporation
has_one :corporation, :through => :user_corporation
end
corporation.rb:
class Corporation < OtherBaseconfiguration
self.table_name = 'Corporations'
has_one :user_corporation
has_one :user, :through => :user_corporation
end
20160212185152_create_user_corporations.rb:
class CreateUserCorporations < ActiveRecord::Migration
def change
create_table :user_corporations do |t|
t.belongs_to :user, index: true
t.belongs_to :corporation, index: true
t.timestamps null: false
end
end
end
rake db: migrate
执行,table 被创建。在控制台中,尝试获取公司用户时,出现错误:
irb(main):006:0> @corpor.corporation
ActiveRecord::StatementInvalid: PG::UndefinedTable: ERROR: relation "user_corporations" does not exist
LINE 5: WHERE a.attrelid = '"user_corporations"'::reg...
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"user_corporations"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:592:in `async_exec'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:592:in `block in exec_no_cache'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/abstract_adapter.rb:472:in `block in log'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/abstract_adapter.rb:466:in `log'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:592:in `exec_no_cache'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:584:in `execute_and_clear'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql/database_statements.rb:160:in `exec_query'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql_adapter.rb:733:in `column_definitions'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/postgresql/schema_statements.rb:186:in `columns'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/schema_cache.rb:43:in `columns'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/connection_adapters/schema_cache.rb:49:in `columns_hash'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/associations/association_scope.rb:85:in `column_for'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/associations/association_scope.rb:94:in `bind'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/associations/association_scope.rb:103:in `last_chain_scope'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activerecord-4.2.5/lib/active_record/associations/association_scope.rb:139:in `add_constraints'
... 13 levels...
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/commands/console.rb:9:in `start'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:68:in `console'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/railties-4.2.5/lib/rails/commands.rb:17:in `<top (required)>'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `block in require'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:240:in `load_dependency'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:274:in `require'
from /home/marson/rails_project/infinity/bin/rails:9:in `<top (required)>'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `load'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `block in load'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:240:in `load_dependency'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/gems/2.2.0/gems/activesupport-4.2.5/lib/active_support/dependencies.rb:268:in `load'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /home/marson/.rvm/rubies/ruby-2.2.3/lib/ruby/site_ruby/2.2.0/rubygems/core_ext/kernel_require.rb:54:in `require'
我做错了什么?
也许我遗漏了它,但如果您只需要公司和用户之间的 has_one 到 has_one,为什么要使用 UserCorporations 查找 table?
您的设计有缺陷,您试图以错误的方式使用 has_one,结果失败了。您想要以下设计之一: 一个
公司有很多用户 用户属于公司
(一个用户只能属于一个公司。一个公司可以有很多用户)。
B
Corporation 有很多 UserCorporations 用户有多个 UserCorporations UsedCorporation属于用户 UserCorporation 属于公司
(这是多对多,所以一个用户可以属于多个军团,一个军团可以有多个用户)
C
公司属于用户 用户拥有多家公司
(一个用户连接多个军团,一个军团只能属于一个用户)
用 has_many :through
做
作为
(公司有很多用户用户 belongs_to
公司)
公司belongs_to
用户用户has_many
公司
(用户连接到多个公司,一个公司只能belong_to
一个用户)
macOS Big Sur 上的情况相同...
bundle list ...
- devise (4.8.0) ...
- pg (1.2.3) ...
- rails (6.1.3.2) ...
模型用户和用户规则(一个用户有一个规则)
class User < ApplicationRecord
has_one :user_rule
end
class DeviseCreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
## Database authenticatable
t.string :username, null: false, default: ""
t.string :email, null: false, default: ""
t.string :encrypted_password, null: false, default: ""
....
end
end
end
class UserRule < ApplicationRecord
belongs_to :user
end
class CreateUserRules < ActiveRecord::Migration[6.1]
def change
create_table :user_rules do |t|
t.belongs_to :user, index: { unique: true }, foreign_key: true
....
end
end
end
config/database.yml
的内容development:
<<: *default
database: <%= ENV['MY_DATABASE_NAME'] %>
host: <%= ENV['MY_DATABASE_HOST'] %>
port: <%= ENV['MY_DATABASE_PORT'] %>
username: <%= ENV['MY_DATABASE_USER'] %>
password: <%= ENV['MY_DATABASE_PASSWORD'] %>
清理数据库:
rake db:drop
rake db:create
rake db:migrate
转到控制台:
rails console
Running via Spring preloader in process 25238
Loading development environment (Rails 6.1.3.2)
2.7.2 :001 > User.new
=> #<User id: nil, username: "", email: "", ....>
2.7.2 :002 > UserRule.new
Traceback (most recent call last):
1: from (irb):2
ActiveRecord::StatementInvalid (PG::UndefinedTable: ERROR: relation "user_rules" does not exist)
LINE 8: WHERE a.attrelid = '"user_rules"'::regclass
如图所示,我的用户模型工作正常,但模型 UserRule 失败...
让我对数据库凭据而不是环境变量的设置进行硬编码...
文件config/database.yml:
development:
<<: *default
database: "app_development"
host: "localhost"
port: "5432"
username: "postgres"
password: "postgres"
重复...
rails console
Running via Spring preloader in process 25238
Loading development environment (Rails 6.1.3.2)
2.7.2 :001 > User.new
=> #<User id: nil, username: "", email: "", ....>
2.7.2 :002 > UserRule.new
=> #<UserRule id: nil, user_id: nil, ...>
哦惊喜!!!
问题不在于 Rails,是在使用环境值时 config/database.yml 中的数据库凭据...
当您在 macOS Big Sur、Intel 系列上工作时,将这些设置硬编码为解决方法。
与 Linux 一起工作就像一个魅力!!!