【问题标题】:Rails - has_many :through associationRails - has_many:通过关联
【发布时间】:2016-01-07 04:04:32
【问题描述】:

我已经设置了一个 has_many :通过用户和组织模型之间的关联,使用会员模型作为连接。

class Organisation < ActiveRecord::Base
    has_many :memberships
    has_many :users, :through => :memberships
end

class User < ActiveRecord::Base
    . . .
    has_many :memberships
    has_many :organisations, :through => memberships
end

class Membership < ActiveRecord::Base
    belongs_to :user
    belongs_to :organisation
end

当用户创建组织时,我希望自动创建将用户链接到该组织的成员资格。

攻击这个的最佳地点在哪里?

我一直在研究的选项:

  1. 在组织上使用 after_create 回调

  2. 将此进程移到单独的 Ruby 类中。

  3. 在组织控制器中,创建操作。

  4. ?

你会建议我怎么做?

Rails 指南中是否有某处概述了此类事情的最佳实践?

导轨 4.2.5。

【问题讨论】:

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


    【解决方案1】:
    #config/routes.rb
    resources :organizations #-> url.com/organizations/new
    
    #app/controllers/organizations_controller.rb
    class OrganizationsController < ApplicationController
       before_action :authenticate_user!
    
       def new
          @organization = current_user.organizations.new
       end
    
       def create
          @organization = current_user.organizations.new organization_params
          @organization.save
       end
    
       private
    
       def organization_params
          params.require(:organization).permit(:x, :y, :z) #-> membership automatically created
       end
    end
    

    以上会自动创建关联的会员;假设您正在使用 Devise 并且可以访问 current_user 方法。

    --

    最佳实践是最简洁的;你不可能“打算”这样做。

    我在 Rails 中看到的最大谬误之一是人们试图找到最可接受的方式来做某事(就像有一本规则手册一样)。你能做的最好的事情是让它工作然后重构代码。

    随着您的应用程序的进展,您会发现某些模式可以更改,某些模式可以删除,还有许多可以组合。您编写的代码越多"DRY",它就越好(通常)。

    【讨论】:

      【解决方案2】:

      我的想法是方式 3。通常,当在模型中设置多 - 多关联时,我们应该通过控制器自动创建临时表记录。
      例如在控制器中你可以写:

      @organisation = current_user.organisations.build organisation_params
      if @organisation.save
        ....
      

      这样,如果@organisation 被保存,然后会员记录自动生成。
      您可以查看本教程以了解:
      http://blog.teamtreehouse.com/what-is-a-has_many-through-association-in-ruby-on-rails-treehouse-quick-tip

      【讨论】:

        【解决方案3】:

        我认为您应该能够执行以下操作:

        org = Organisation.new
        org.otherstuff = "populate other stuff"
        org.users = [user_who_created]
        org.save
        

        之后这两者应该是相关的......?如果你想封装这种行为,你可以在 Organization 上创建一个类方法,如 create_org_for_user(name, user),然后在其中执行此逻辑,或者您可以在处理创建的控制器操作中执行此操作。

        【讨论】:

          【解决方案4】:

          如果除了创建组织和成员之外没有任何其他逻辑,我只会执行 #3。但是,如果您计划在将来为创建新组织添加更多逻辑,我会创建一个新的service (#2)。

          【讨论】:

            【解决方案5】:

            攻击这个的最佳地点在哪里?

            我想说你应该把这个写在OrganisationsController'screate动作中,以便在更新动作上也做一个DRY(使用强参数)。因为你是表单属性获取来自外部世界,最好使用强参数概念在required params 上使用permit method

            def create
               @organisation = Organisation.new(organisation_params)
               ...
            end
            
            def organisation_params
                # here you could write all the params which you want to permit from outer worlds
            end
            

            没有更多关于Strong Parameters的信息

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-01-27
              • 2013-05-06
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-08-24
              • 2017-11-27
              相关资源
              最近更新 更多