Rails has_and_belongs_to_many& has_many:通过脚手架

时间:2011-10-10 05:25:06

标签: ruby ruby-on-rails-3 scaffolding

有没有办法为具有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  

......其中许多都以“我如何......”开头。所以看起来这个话题对于SO用户来说并不是微不足道的。我猜我想知道它为什么没有引起注意。事情比看起来更复杂吗? Rails的功能集似乎非常广泛。我一直在想为什么省略了与连接表关联的脚手架。

请把你的答案集中在上面的断言或“包含声明”,脚手架必须包括......“或”轨道生成脚本需要......“

谢谢!

1 个答案:

答案 0 :(得分:8)

我喜欢你的问题,我自己也想知道为什么这不包含在Rails中(并且我怀疑不能作为Gem使用)。以下是可能成为问题的一些原因。我会让他们在assembliesparts的典型示例中进行解释。

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

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

    这意味着没有添加文件或更改文件的概念。 编辑:事实并非如此,有机制可以添加到文件甚至更改文件。

  2. 如果你看一下例如has_many :through(应与has_and_belongs_to_many类似)您必须执行以下操作:

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

      ==>脚手架应该可以做:rails g scaffold_hmt Assembly Part

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

      ==>以前的脚手架应该可以用于脚手架。

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

      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视图中的问题相同。
  3. 总而言之,脚手架值得一试(见下段)。至少Creating and Customizing Rails Generators & Templates的RailsGuides似乎是合理的。并且生成部分文件的解决方案,相应地命名它们并帮助控制台上的脚手架输出以便手动完成剩下的工作可能值得一试。


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

    1. 将目录scaffold_hmt(代表has_many :through)的内容复制到rails应用程序目录lib/generators
    2. 您可以使用以下代码调用生成器:rails g scaffold_hmt Assembly Part
    3. 然后会生成:
      • 迁移连接表
      • 联接表的模型
    4. 无法更改文件:

      • 型号assembly.rb
      • 型号part.rb

      原因在于找到合适的地方并非易事。作为一种解决方法,它会打印出应该插入到文件中的内容。

      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
      
    5. 试一试,看看这对你有帮助。