Я создал модели пользователя и местоположения (и модель продукта тоже, но одна проблема за раз), и когда я играл с консолью, я был удивлен некоторые из результатов.Не уверен, что моя ассоциация пользователей и местоположений с Rails 4
Модели
Class User < ActiveRecord::Base
# Before saving filters
before_save { self.email = email.downcase }
before_save :create_remember_token
# Validations
validates :name, presence: true,
length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.][email protected][a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true,
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }
validates :password_confirmation, presence: true
# Associations
has_many :owned_products, class_name: "Product",
foreign_key: "owner_id",
dependent: :destroy
has_many :borrowed_products, class_name: "Product",
foreign_key: "borrower_id"
belongs_to :location
private
def create_remember_token
self.remember_token = SecureRandom.urlsafe_base64
end
end
Class Product < ActiveRecord::Base
validates :name, presence: true,
length: { maximum: 50 }
validates :owner, presence: true
belongs_to :owner, class_name: "User", foreign_key: "owner_id"
belongs_to :borrower, class_name: "User", foreign_key: "borrower_id"
belongs_to :location
end
Class Location < ActiveRecord::Base
has_many :users
has_many :products
end
Миграции
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.string :password_digest
t.string :remember_token
t.integer :location_id
t.timestamps
end
add_index :users, :email, unique: true
add_index :users, :remember_token
add_index :users, :location_id
end
end
class CreateProducts < ActiveRecord::Migration
def change
create_table :products do |t|
t.string :name
t.integer :location_id
t.timestamps
end
add_index :products, :location_id
end
end
class CreateLocations < ActiveRecord::Migration
def change
create_table :locations do |t|
t.string :address
t.timestamps
end
end
end
Место Атрибуты accessibles
class UsersController < ApplicationController
.
.
.
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation, :location, :location_attributes)
end
end
Тогда я иду в консоль и введите:
User.create(name: "Wahou", email: "[email protected]", password: "motdepasse", password_confirmation: "motdepasse")
Что дает мне:
(0.2ms) begin transaction
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('[email protected]') LIMIT 1
Binary data inserted for `string` type on column `password_digest` SQL (1.1ms) INSERT INTO "users" ("created_at", "email", "name", "password_digest", "remember_token", "updated_at") VALUES (?, ?, ?, ?, ?, ?) [["created_at", Fri, 24 May 2013 12:27:38 UTC +00:00], ["email", "[email protected]"], ["name", "Wahou"], ["password_digest", "$2a$10$OhJ7SLA.vxO4N8IkZAXXQOibYQoX6G6E9/mGgmDpm8Hj48p8riDE."], ["remember_token", "-O72ULpG2tjrZSSi0BFB5A"], ["updated_at", Fri, 24 May 2013 12:27:38 UTC +00:00]]
(148.6ms) commit transaction
=> #<User id: 1, name: "Wahou", email: "[email protected]", password_digest: "$2a$10$OhJ7SLA.vxO4N8IkZAXXQOibYQoX6G6E9/mGgmDpm8Hj...", remember_token: "-O72ULpG2tjrZSSi0BFB5A", admin: false, location_id: nil, created_at: "2013-05-24 12:27:38", updated_at: "2013-05-24 12:27:38">
Тогда я типа:
Location.create(address: "1, rue des prises de tête - Paris")
Который дает мне:
(0.2ms) begin transaction
SQL (6.0ms) INSERT INTO "locations" ("address", "created_at", "updated_at") VALUES (?, ?, ?) [["address", "1, rue des prises de tête - Paris"], ["created_at", Fri, 24 May 2013 12:27:22 UTC +00:00], ["updated_at", Fri, 24 May 2013 12:27:22 UTC +00:00]]
(121.6ms) commit transaction
=> #<Location id: 1, address: "1, rue des prises de tête - Paris", street: nil, city: nil, postal_code: nil, country: nil, longitude: nil, latitude: nil, created_at: "2013-05-24 12:27:22", updated_at: "2013-05-24 12:27:22">
Таким образом, полностью уверен, я могу это сделать:
User.first.location = Location.first
Который дает мне:
User Load (0.5ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
Location Load (0.4ms) SELECT "locations".* FROM "locations" ORDER BY "locations"."id" ASC LIMIT 1
=> #<Location id: 1, address: "1, rue des prises de tête - Paris", street: nil, city: nil, postal_code: nil, country: nil, longitude: nil, latitude: nil, created_at: "2013-05-24 12:27:22", updated_at: "2013-05-24 12:27:22">
И когда я печатаю User.first.location
, это дает мне nil
!
Так что, я думаю, что-то кое-что забыл. У вас есть идея?
(Если заменить пользователя на продукт, это сделать то же самое ...)
EDIT
Я попытался ввести только User.first.location_id = 1
и User.first.location
всегда nil
.
Единственный способ найти имя на картинке для его поиска - это создать его с местонахождением, просто так: Location.first.users.create(name: "Wahou", email: "[email protected]", password: "motdepasse", password_confirmation: "motdepasse")
. И затем, это работает ... Но что я могу сделать, когда хочу обновить местоположение моего пользователя?
EDIT 2
Когда я печатаю
u = User.first
Я вижу первый Пользователь схватился:
User Load (0.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
=> #<User id: 2, name: "Numero1 Person", email: "[email protected]", password_digest: "$2a$10$sNwoTjOL4eqW.clxbM5FcuiE0AmPgzr8Kz0ewXgddAvP...", remember_token: "OQ2ZnLhPutwePTqn49r5PQ", admin: false, location_id: 2, created_at: "2013-05-29 07:59:13", updated_at: "2013-05-29 09:22:00">
Тогда я повлиять Location.first на мой первый пользователя место нахождения:
u.location = Location.first
Я вижу первое место хватают:
Location Load (0.4ms) SELECT "locations".* FROM "locations" ORDER BY "locations"."id" ASC LIMIT 1
=> #<Location id: 1, address: "1, rue longue - 99999 LOIN - France", street: "1, rue longue", city: "LOIN", postal_code: 99999, country: "France", longitude: nil, latitude: nil, created_at: "2013-05-29 07:59:38", updated_at: "2013-05-29 07:59:38">
Но когда я хочу сохранить его ...
u.save
... Это не работает!
(0.1ms) begin transaction
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE (LOWER("users"."email") = LOWER('[email protected]') AND "users"."id" != 2) LIMIT 1
(0.2ms) rollback transaction
=> false
EDIT 3
Если я пытаюсь ввести следующий код ...
User.first.update_attributes(location: Location.first)
Он посылает меня, что:
User Load (0.4ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT 1
Location Load (0.3ms) SELECT "locations".* FROM "locations" ORDER BY "locations"."id" ASC LIMIT 1
(0.1ms) begin transaction
User Exists (0.4ms) SELECT 1 AS one FROM "users" WHERE (LOWER("users"."email") = LOWER('[email protected]') AND "users"."id" != 2) LIMIT 1
(0.2ms) rollback transaction
=> false
SOLVED
Позор на меня! Я забываю добавить пароль и пароль_подтверждения в мои update_attributes. Если я это сделаю, это сработает!
Вот правильный код:
User.first.update_attributes(password: "password", password_confirmation: "password", location: Location.first)
Спасибо, но это не сработало :-( –