0

Я создал модели пользователя и местоположения (и модель продукта тоже, но одна проблема за раз), и когда я играл с консолью, я был удивлен некоторые из результатов.Не уверен, что моя ассоциация пользователей и местоположений с 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) 

ответ

0

Да, вы забыли, чтобы сохранить изменения.

u = User.first # => <User id: 1, name: "Wahou".... 
l = Location.first #=> <Location id: 1, address: "1 rue..... 

# set the location 
u.location = l 

#Save changes 
u.save 

#profit 
User.first.location 
+0

Спасибо, но это не сработало :-( –

1

@Aurel дал вам правильный намек. Для объяснения:

выполнения

User.first.location_id = 1 

загружает первый пользователь во временный объект, затем устанавливает LOCATION_ID, а затем выбрасывает его без сохранения. Вот почему ваше изменение не является постоянным.

@

u= User.first 
u.location = Location.first 
u.save 

нагрузок Аурел первый пользователь в u, задает расположение u, а затем сохраняет его, чтобы сделать его стойким.После этого

User.first.location 

дает объект Location.first

Другим способом является пользователем update_attribut, который устанавливает атрибут и сохраняет изменения, так

User.first.update_attribute :location, Location.first 

также работает и делает изменения постоянными.

+0

Спасибо, Мартин, работает последняя строка. Но я не понимаю, почему, потому что, когда я делаю 'User.first.update_attributes (location: Location.first) ', это не сработает, но если я сделаю это во всем новом приложении rails, только с моделями (без контроллеров или представлений),' User.first.update_attributes (location: Location.first) 'работает. странно И для записи, путь @ Aurel вообще не работал ... –

+0

'update_attribute' нуждается в двух аргументах: имени атрибута и значении.' func (location: Location.first' вызывает 'func' с ** one ** hash аргумент: '{location: Location.fist}'. Это не работает с 'update_attribute' –

+0

Я думаю, что нашел что-то [здесь] (http://www.davidverhasselt.com/2011/06/28/5-пути-к-SET-атрибуты-в-activerec Ord /). Метод update_attribute работает, потому что ему не нужны проверки и массовое присвоение. Если update_attributes не работает, это значит, что что-то не так с моими проверками или с помощью защиты mass_assignement, не так ли? –

 Смежные вопросы

  • Нет связанных вопросов^_^