我是rails的新手,我想知道如何获取一对一的关系。我想要获取用户城市。在我的postgresql数据库中,我有:
cities Table:
city:varchar
zipcode: integer
users Table
name:varchar
city_id:int
在城市和用户模型中我有:
class City < ActiveRecord::Base
belongs_to :user
end
class User < ActiveRecord::Base
has_one :city
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
end
我在搜索控制器中尝试了以下操作,但在登录时无效:
current_user.city
我收到以下错误
Processing by SearchController#index as HTML
Parameters: {"utf8"=>"✓", "q"=>"", "criteria"=>"1", "commit"=>"Search"}
User Load (1.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = 6 ORDER BY "users"."id" ASC LIMIT 1
PG::UndefinedColumn: ERROR: column cities.user_id does not exist
LINE 1: SELECT "cities".* FROM "cities" WHERE "cities"."user_id" =...
^
: SELECT "cities".* FROM "cities" WHERE "cities"."user_id" = $1 LIMIT 1
Completed 500 Internal Server Error in 11ms
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column cities.user_id does not exist
LINE 1: SELECT "cities".* FROM "cities" WHERE "cities"."user_id" =...
^
: SELECT "cities".* FROM "cities" WHERE "cities"."user_id" = $1 LIMIT 1):
为什么我想在users表中添加一个user_id列,当我在users表中有城市外键时?我不想将user_id添加到cities表中。
答案 0 :(得分:1)
查看has_one和belogns_to的文档,
belongs_to(name, options = {})
Specifies a one-to-one association with another class. This method should only be used if this class
contains the foreign key. If the other class contains the foreign key, then you should use has_one
instead.
由于用户表具有外键,您应该像这样更改模型定义
class City < ActiveRecord::Base
has_one :user
end
class User < ActiveRecord::Base
belongs_to :city
end
答案 1 :(得分:1)
您可以将has_one :through association
与联接表一起使用。下面给你一些例子。
用户模型:
class User < ActiveRecord::Base
has_one :city, through: :user_city
has_one :user_city
end
城市模型:
class City < ActiveRecord::Base
belongs_to :user
end
用户城市加入模式:
class UserCity < ActiveRecord::Base
belongs_to :city
belongs_to :user
end
连接表的迁移:
class JoinUserCity < ActiveRecord::Migration
def change
create_table :user_cities do |t|
t.integer :user_id
t.integer :city_id
end
end
end
在rails控制台中测试:
=> u = User.create
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "users" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2014-12-07 15:47:14.595728"], ["updated_at", "2014-12-07 15:47:14.595728"]]
(3.3ms) commit transaction
=> #<User id: 4, created_at: "2014-12-07 15:47:14", updated_at: "2014-12-07 15:47:14">
=> u.city
City Load (0.2ms) SELECT "cities".* FROM "cities" INNER JOIN "user_cities" ON "cities"."id" = "user_cities"."city_id" WHERE "user_cities"."user_id" = ? LIMIT 1 [["user_id", 4]]
=> nil
=> c = City.create
(0.1ms) begin transaction
SQL (0.5ms) INSERT INTO "cities" ("created_at", "updated_at") VALUES (?, ?) [["created_at", "2014-12-07 15:47:24.535039"], ["updated_at", "2014-12-07 15:47:24.535039"]]
(3.3ms) commit transaction
=> #<City id: 1, created_at: "2014-12-07 15:47:24", updated_at: "2014-12-07 15:47:24">
irb(main):004:0> u.city = c
UserCity Load (0.3ms) SELECT "user_cities".* FROM "user_cities" WHERE "user_cities"."user_id" = ? LIMIT 1 [["user_id", 4]]
(0.1ms) begin transaction
SQL (0.4ms) INSERT INTO "user_cities" ("city_id", "user_id") VALUES (?, ?) [["city_id", 1], ["user_id", 4]]
(1.0ms) commit transaction
=> #<City id: 1, created_at: "2014-12-07 15:47:24", updated_at: "2014-12-07 15:47:24">
irb(main):005:0> u.save
(0.1ms) begin transaction
(0.1ms) commit transaction
=> true
=> u = User.last
User Load (0.3ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
=> #<User id: 4, created_at: "2014-12-07 15:47:14", updated_at: "2014-12-07 15:47:14">
=> u.city
City Load (0.2ms) SELECT "cities".* FROM "cities" INNER JOIN "user_cities" ON "cities"."id" = "user_cities"."city_id" WHERE "user_cities"."user_id" = ? LIMIT 1 [["user_id", 4]]
=> #<City id: 1, created_at: "2014-12-07 15:47:24", updated_at: "2014-12-07 15:47:24">