Rails ActiveRecorde has

xiaoxiao2026-08-29  24

使用的是rails2.0.2版本,。现有表结构如下: create table mc$dr_role(id number primary key,role varchar2(30),enabled varchar2(10))create table mc$dr_user_roles(id number primary key,user_id number ,role_id number)create table users(id number primary key,name varchar2(30) ,passwd varchar2(30)) 在model中写法是: class Role < ActiveRecord::Baseset_table_name "mc$dr_role" has_many :user_roles, :class_name =>"DrUserRole", :foreign_key=>"id", :dependent=> :delete_all has_many :users, :through => :user_rolesendclass User < ActiveRecord::Base has_many :user_roles, :class_name =>"DrUserRole", :foreign_key=>"id", :dependent=> :destroy has_many :roles, :through => :user_rolesendclass DrUserRole < ActiveRecord::Baseset_table_name "mc$dr_user_roles"belongs_to :user, :class_name =>"User", :foreign_key=>"user_id" belongs_to :role, :class_name =>"Role", :foreign_key=>"role_id"end 在执行@user.roles << role 报错Cannot associate new records through 'User#user_roles' on '#'. Both records must have an id in order to create the has_many :through record associating them. 我很奇怪关联中“#”是哪里出来的?没弄明白。foreign_key这个配置选项我都已经尝试过好几次变化了,都没成功。。。不知道原因在那里?还是对于这样自定义的表进行关联式有问题的? 正常来说 按照你所需要的建多对多关联表 是这样弄的 ruby generate model role role:string enable:stringruby generate model user name:string pass:stringruby generate model UserRole user_id:integer role_id:integerrake db:migrate 就生成对应的表和字段了 然后是model class Role < ActiveRecord::Base has_many :user_roles,:dependent=> :destroy has_many :users, :through => :user_rolesendclass User < ActiveRecord::Base has_many :user_roles,:dependent=> :destroy has_many :roles, :through => :user_rolesendclass DrUserRole < ActiveRecord::Basebelongs_to :userbelongs_to :roleend over 你的错误应该是指定了错误的外键 导致的.. 对于belongs_to :foreign_key是默认的,除非你的,主键不是id,如果你只是修改了table没有改field名的话,考虑去掉:foreign_key。 参考官方API [quote]:foreign_key Specify the foreign key used for the association. By default this is guessed to be the name of the association with an "_id" suffix. So a class that defines a belongs_to :person association will use "person_id" as the default :foreign_key. Similarly, belongs_to :favorite_person, :class_name => "Person" will use a foreign key of "favorite_person_id".[/quote] 那么,楼主的问题在哪呢? 楼主最主要不一样的地方是,打破了一个默认规则,就是不希望,物理表名和Model名一致。 实际,对于这样的需要只需要set_table就够了,也就是model写成这样 class Role < ActiveRecord::Baseset_table_name "mc$dr_role" has_many :dr_user_roles, :dependent=> :delete_all has_many :users, :through => :dr_user_rolesendclass User < ActiveRecord::Base has_many :dr_user_roles, :dependent=> :destroy has_many :roles, :through => :dr_user_rolesendclass DrUserRole < ActiveRecord::Baseset_table_name "mc$dr_user_roles" belongs_to :user belongs_to :roleend 那么,最开始说了,什么时候用指定:foreign_key 接着看看,什么时候用:class_name,这个应该是,只有定义的关系和类名不一致的时候。例如:假设楼主,很坚持使用user_roles,就可以按下面写 Ruby代码 class Role < ActiveRecord::Baseset_table_name "mc$dr_role" has_many :user_roles, :class_name =>"DrUserRole", :dependent=> :delete_all has_many :users, :through => :user_rolesendclass User < ActiveRecord::Base has_many :user_roles, :class_name =>"DrUserRole", :dependent=> :destroy has_many :roles, :through => :user_rolesendclass DrUserRole < ActiveRecord::Baseset_table_name "mc$dr_user_roles" belongs_to :user belongs_to :roleend 换句话说,这里没有问题,没有不一致的问题。 只是,不应该指定一个,不太合逻辑的foreign_key。也就是说belongs_to的class_name和forein_key可以不去掉,顶多就是重复写了一遍。has_many的foreign_key也可以去掉,因为和默认的外键是一样的,毕竟你的id还是主键。 那么,如果楼主说了,我就偏要写呢, 嗯,也可以,那就像楼上说的,那得把foreign_key写对。 has_many的默认foreign_key是什么呢,那就要看看逻辑啦 你有很多子表,那么外键就是你的主键了,所以应该是,主表名加主id。 或者,也可以参考,官方API :foreign_key# Specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and "_id" suffixed. So a Person class that makes a has_many association will use "person_id" as the default :foreign_key. 也就是说,楼主的Model写成下面的,也没问题。 class Role < ActiveRecord::Baseset_table_name "mc$dr_role" has_many :user_roles, :class_name =>"DrUserRole", :foreign_key=>"role_id", :dependent=> :delete_all has_many :users, :through => :user_rolesendclass User < ActiveRecord::Base has_many :user_roles, :class_name =>"DrUserRole", :foreign_key=>"user_id", :dependent=> :destroy has_many :roles, :through => :user_rolesendclass DrUserRole < ActiveRecord::Baseset_table_name "mc$dr_user_roles"belongs_to :user, :class_name =>"User", :foreign_key=>"user_id" belongs_to :role, :class_name =>"Role", :foreign_key=>"role_id"end 最后,说说,为什么:foreign_key写成id的问题,@user.roles能找到,但添加会有问题呢? 因为,:foreign_key写成id,@user.roles就变成 DrUserRole.find_by_id(@user.id) 而不是,正确的 DrUserRole.find_by_user_id(@user.id)
转载请注明原文地址: https://www.6miu.com/read-5052041.html

最新回复(0)