2014-12-07 2 views
0

Я новичок в рельсах, и я хочу знать, как получить отношения «один-к-одному». Я хочу получить город пользователей. В моей базе данных PostgreSQL У меня есть:howto call one-to-one отношения в рельсах

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): 

Почему я полагаю, чтобы добавить столбец user_id в таблицу городов, когда у меня есть иностранный ключ городов в таблице пользователей? Я не хочу добавлять user_id в таблицу городов.

+0

, потому что я только хочу, чтобы иметь почтовый индекс и город в таблице городов. Затем я хочу, чтобы активная запись приносила мне этот объект города для моего пользователя. –

+0

[согласно руководствам по rails для has_one] (http://guides.rubyonrails.org/association_basics.html#the-has-one-association). Эта ассоциация указывает, что каждый экземпляр модели содержит или обладает одним экземпляром другой модели. «Итак, ваш пользователь имеет только один город? или вы имеете в виду многие из многих ассоциаций? ([где у многих пользователей может быть много городов?] (http://guides.rubyonrails.org/association_basics.html#the-has-and-belongs-to-many-association)) i думаю, что вы ищете ['has_one: via Association'] (http://guides.rubyonrails.org/association_basics.html#the-has-one-through-association) –

+0

yes 1 пользователь имеет 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 

Тест на рельсах консоли:

=> 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"> 
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