Rails has_and_belongs_to_many 和 has_many :through 的脚手架搭建

23

有没有一种方法可以为具有has_and_belongs_to_many或has_many:through关系的Rails模型生成脚手架?如果没有,是否有开发原因导致某些基本形式的此功能未被包含在内?Rails要求开发人员生成和编辑“自定义”“连接表迁移”。这种需要对细节的关注是提醒Rails开发人员某些重要事实的方式还是Rails作为“不断改进”的一个例子?

快速搜索Stackoverflow:

"has_and_belongs_to_many" yields 821 questions  
"has_many :through" yields 933 questions  

许多问题都以“How do I…”开头,因此这个主题似乎并不平凡,是与SO用户相关的。我想知道为什么它没有得到关注。这个问题比看起来更复杂吗?Rails的功能集似乎非常广泛。我一直在想为什么联接表关联的脚手架被省略了。

请将您的答案重点放在上述论断上,或者像“一个脚手架需要包括…”或“一个Rails生成脚本需要…”这样的陈述。

谢谢!


1
我本来期望这个在Rails 5中已经可以工作了:rails generate model company name:string industry:has_and_belongs_to_many,它会在company模型中添加has_and_belongs_to_many: :industry - Chloe
1个回答

9

我喜欢你的问题,我自己也想知道为什么Rails没有包含这个功能(我猜作为Gem也不可用)。以下是可能存在问题的一些原因。我将通过assembliesparts的典型示例来解释它们。

  1. Scaffolding通过使用生成器来创建文件。如果您迁移到新版本,有时可以通过执行以下步骤来更新现有文件:

    • 将现有文件复制到新名称。
    • 用新文件覆盖现有文件。

    这意味着没有添加文件或更改文件的概念。 EDIT: 这不是正确的,有机制可以添加到文件甚至在文件中进行更改。

  2. 如果您查看例如has_many :through(应类似于has_and_belongs_to_many)的生成,则必须执行以下操作:

    • 添加创建连接表的迁移。

      ==> 通过执行rails g scaffold_hmt Assembly Part,scaffolding应该是可能的。

    • 添加该连接模型的模型。

      ==> 通过之前的脚手架工具,scaffolding应该是可能的。

    • 更改现有模型以包括以下行:

      assembly.rb:has_many 'assemblies_parts'; has_many :parts, :through => 'assemblies_parts'

      part.rb:has_many 'assemblies_parts'; has_many :assemblies, :through => 'assemblies_parts'

      ==> 因此无法进行脚手架工具

    • 如何处理视图是完全开放的。有RailsCast上的示例可供参考,但这并不是所有情况下都能很好地工作的单一技术。我认为可以将不同的模式实现为脚手架的模板(例如使用复选框或多选列表或带完成的文本输入)。然而,问题与has_many视图相同。

总之,脚手架可能值得一试(请参见下一段)。RailsGuides中的创建和自定义Rails生成器和模板看起来至少是可行的。并且,生成文件的部分、相应地命名它们并帮助在控制台上输出脚手架以手动完成其余部分的解决方案可能值得一试。


我昨天尝试提供了一个部分解决方案,你可以在GitHub上查看它。它的工作原理如下:

  1. Copy the contents of the directory scaffold_hmt (stands for has_many :through) to your rails application directory lib/generators.
  2. You may call then the generator with: rails g scaffold_hmt Assembly Part.
  3. It will then generate:
    • Migration for the join table
    • Model for the join table
  4. It fails to change the files:

    • Model assembly.rb
    • Model part.rb

    The reason for that is that the finding of the right place is not trivial. As a workaround, it prints out what should have inserted into the files.

    c:\apps\ruby\rails3\minds>rails generate scaffold_hmt Assembly Part
          create  db/migrate/20111011135944_create_assemblies_parts.rb
          create  app/models/assemblies_part.rb
    Try to insert into file: app/models/assembly.rb the following statements:
    
    has_many :assemblies_parts
    has_many :parts, :through => :assemblies_parts
          insert  app/models/assembly.rb
    Try to insert into file: app/models/part.rb the following statements:
    
    has_many :assemblies_parts
    has_many :assemblies, :through => :assemblies_parts
          insert  app/models/part.rb
    

试一试,看看是否有帮助。


感谢您的回复。所以一个问题是支持现有文件的更改。这会使得生成脚手架的三步过程不可逆转吗?例如 (1) rails generate MyModels 和 my_columns (2) rake db:migrate (3) rake joinHack MyModels MyJoinTable ... 第三步会进行您提到的文件更改吗?我想这仍然让 Views 成为一个未决问题。 - Perry Horwich
拥有一些非常基本的视图是否有价值?也许在视图或模型代码中包含一条注释免责声明:“这只是使用某某东西的一种方法。请参阅此Railsguide了解更多信息。” - Perry Horwich
我猜步骤(1)也应该声明类似的内容:“要完成这个三步骤的过程,请现在做这个和那个。请注意,步骤(3)代表了一个不可逆转的步骤。祝你有愉快的一天。” - Perry Horwich
1
在GitHub上添加了一个示例实现,该实现部分解决了问题。 - mliebelt
1
我最近添加了一个示例应用程序,其中没有包含has_many :through关系,并修复了生成器中的一些错误。现在它应该可以使用了。 - mliebelt
太棒了。我已经在 GitHub 上发布了第一个“问题”。 - Perry Horwich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接