在我的项目中,我陷入了一个问题:项目应该能够使用至少一种语言,语言有很多项目。我创建了这样的模型:
class Project < ActiveRecord::Base
belongs_to :developer, counter_cache: true
has_many :languages
validates :developer, presence: true
validates :name, presence: true, uniqueness: true
validates :description, presence: true
end
和
class Language < ActiveRecord::Base
has_many :projects
end
我为DB添加了3种语言。 现在我应该能够用某种语言创建一个项目:
p = Project.create :developer_id=>"1", :language_id=>"2", :name=>"Project 1", :description=>"Sample project"
它说:
ActiveRecord::UnknownAttributeError: unknown attribute 'language_id' for Project.
我有这种ID的语言然后为什么它不能添加一个。这可能是语言的问题 - &gt;他们没有项目,但有关系:has_many:projects
期待收到你们的回复:
编辑: 现在它看起来像:
class Language < ActiveRecord::Base
has_and_belongs_to_many :projects
end
class Project < ActiveRecord::Base
belongs_to :developer, counter_cache: true
has_and_belongs_to_many :languages
validates :developer, presence: true
validates :name, presence: true, uniqueness: true
validates :description, presence: true
end
我使用了rails g migration CreateProjectsLanguages project:references language:references
它返回:
p.languages.build(:name => "English")
PG::UndefinedTable: BŁĄD: relacja "languages_projects" nie istnieje
LINE 5: WHERE a.attrelid = '"languages_projects"'::re...
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"languages_projects"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
ActiveRecord::StatementInvalid: PG::UndefinedTable: BŁĄD: relacja "languages_projects" nie istnieje
LINE 5: WHERE a.attrelid = '"languages_projects"'::re...
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod),
pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"languages_projects"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
它看起来无法找到它们之间的关系(可能关联表应该看起来不同)
答案 0 :(得分:3)
您应该为多对多关系使用关联表。在rails中,您可以使用has_many:models映射实体,通过:associative_table_name。
class Project < ActiveRecord::Base
has_many :language_projects
has_many :projects, through: :language_projects
end
class LanguageProject < ActiveRecord::Base
belongs_to :project
belongs_to :language
end
class Language < ActiveRecord::Base
has_many :language_projects
has_many :projects, through: :language_projects
end
http://guides.rubyonrails.org/association_basics.html#the-has-many-through-association
在您的情况下,您可以为关联表生成模型和迁移:
rails g model LanguageProject project:references language:references
如果您不需要将关联表用作模型,则可以使用has_and_belongs_to_many直接映射实体。
class Project < ActiveRecord::Base
has_and_belongs_to_many :languages
end
class Language < ActiveRecord::Base
has_and_belongs_to_many :projects
end
在这种情况下,您只能生成迁移。您将只获得空壳,因此您必须手动编辑文件
rails g migration CreateLanguagesProjectsJoinTable
class CreateLanguagesProjectsJoinTable < ActiveRecord::Migration
def change
create_table :languages_projects, id: false do |t|
t.integer :language_id
t.integer :project_id
end
end
end
然后你应该能够以这种方式关联模型
p = Project.new(:name => 'myproj')
p.languages.build(:name => 'ruby')
p.save
答案 1 :(得分:0)
使用has_many :through或has_and_belongs_to_many。它们的机制是相同的,除了has_many :through
有其他模型。