通过第三个表插入数据

时间:2015-12-27 10:49:28

标签: ruby ruby-on-rails-4 activerecord has-many-through

我有3个模型(客户端,用户和管理员)没有控制器

class Admin < ActiveRecord::Base
    validates_presence_of :username, :user_id, :client_id
    belongs_to :client
    belongs_to :user
end

class Client < ActiveRecord::Base
    validates_presence_of :name
    has_many :admins
    has_many :users, :through => :admins
end

class User < ActiveRecord::Base
    validates_presence_of :name, :email
    has_many :admins
    has_many :clients, :through => :admins
end

所以当我在做

u = User.first.clients.new(name: 'First Client')
u.save

然后一切正常

(0.2ms)  begin transaction SQL (0.6ms)  INSERT INTO "clients" ("name",
"created_at", "updated_at") VALUES (?, ?, ?)  [["name", "First
Client"], ["created_at", "2015-12-27 10:38:47.790787"], ["updated_at",
"2015-12-27 10:38:47.790787"]]    (98.3ms)  commit transaction  =>
true

但是当我试着看

2.2.2 :130 >   User.first.clients
User Load (0.5ms)  SELECT  "users".* FROM "users"  ORDER BY "users"."id" ASC LIMIT 1   Client Load (0.2ms)  SELECT "clients".* FROM "clients" INNER JOIN "admins" ON "clients"."id" = "admins"."client_id" WHERE "admins"."user_id" = ?  [["user_id", 1]] => #<ActiveRecord::Associations::CollectionProxy []>

那么如何将数据插入第三个表? 我已经搜索了很多关于此但没有解决方案,因为这里的复杂性是第三个表Admin也有它的强制列Username。 另外,如何通过此User表将数据插入ClientAdmin表。

3 个答案:

答案 0 :(得分:1)

我知道我已在评论中说明了这一点,但它确实有效:

由于Admin模型已对username进行了验证,因此无法将client添加到user.clients集合中,因为它会导致ActiveRecord ::验证错误。

相反,您应该单独执行这些步骤,或者创建一个可以同时执行所有操作的方法:

  1. 制作用户对象:user = User.create(name: "name", email: "email@email.com")
  2. 制作客户对象client = Client.create(name: "name")
  3. 制作管理对象admin = Admin.create(username: "username", user: user, client: client)
  4. 这将创建必要的表条目,因此当您检查user.clients时,它将查找adminsuser_id = user.id中的所有条目,然后检索所有相应的客户端。

    如果您在控制台中执行此操作,则在执行所有步骤后,请在您的用户实例上重新加载以查看客户端: user.reload.clients

    为了使代码更有条理并同时执行所有这些步骤,您可以将其包装在用户实例方法中。例如:

    用户类

    def add_client(client_name, admin_username)
      client = Client.create(name: client_name)
      admin = Admin.create(username: admin_username, client: client, user: self)
    end
    

答案 1 :(得分:0)

当你创建像u = User.first.clients.new(name: 'First Client')这样的客户时 它仅插入行和写入列name, created_at, updated_at

当你像这样打电话给User.first.clients时,
它找到User.first拥有的管理员。然后由管理员找到客户。

因此,没有管理员与您首先创建的客户有关系。

创建客户端时,您应该设置admin_id(此列可能存在于clients表中),如此

user = User.first
client = user.clients.create(name: 'xxx')
user.clients << client

答案 2 :(得分:0)

让我逐一回答你的问题

  

1:那么如何将数据插入第三个表

正如official document

中所述

4.3.1 has_many添加的方法

  

当您声明has_many关联时,声明类   自动获得与该关联相关的 16种方法

collection<<(object, ...)

在你的情况下

u = User.first.clients.new(name: 'First Client')

应该是

clients = User.first.clients
client = Client.new(name: 'First Client')
clients << client
  

集合&lt;&lt;方法将一个或多个对象添加到集合中   将其外键设置为调用模型的主键。

  

2:User.first.clients如何运作

collection(force_reload = false)
  

collection方法返回所有关联的数组   对象。如果没有关联对象,则返回空   阵列。

希望这有助于您正确理解!!!