【问题标题】:Add record to a has_and_belongs_to_many relationship将记录添加到 has_and_belongs_to_many 关系
【发布时间】:2011-02-13 23:12:45
【问题描述】:

我有两个模型,用户和促销。这个想法是一个促销可以有很多用户,一个用户可以有很多促销。

class User < ActiveRecord::Base
  has_and_belongs_to_many :promotions
end

class Promotion < ActiveRecord::Base
  has_and_belongs_to_many :users
end

我还有一个promotions_users 表/模型,没有自己的ID。它引用了 user_id 和 Promotions_id

class PromotionsUsers < ActiveRecord::Base
end

那么,如何将用户添加到促销活动中?我尝试过这样的事情:

user = User.find(params[:id])
promotion = Promotion.find(params[:promo_id])
promo = user.promotions.new(promo)

这会导致以下错误:

NoMethodError: undefined method `stringify_keys!' for #<Promotion:0x10514d420>

如果我改用这条线: 促销= user.promotions.new(promo.id)

我收到此错误:

TypeError: can't dup Fixnum

我确信我的问题有一个非常简单的解决方案,但我只是没有以正确的方式寻找解决方案。

【问题讨论】:

    标签: ruby-on-rails has-and-belongs-to-many relationship


    【解决方案1】:
    user = User.find(params[:id])
    promotion = Promotion.find(params[:promo_id])
    user.promotions << promotion
    

    user.promotions 是与用户相关的促销活动数组。

    请参阅apidock,了解您可用的所有不同功能。

    【讨论】:

    • 感谢您的快速回复。我觉得我把事情复杂化了。
    • @Coolguy123 是的,collection&lt;&lt;(object, …) 是 collection.push 和 collection.concat 的别名。这会立即触发更新 sql,而无需等待父对象上的保存或更新调用。
    【解决方案2】:

    你可以这样做

    User.promotions = promotion #notice that this will delete any existing promotions
    

    User.promotions << promotion
    

    你可以阅读has_and_belongs_to_many关系here

    【讨论】:

    • 小心User.promotions = promotion,因为这将删除任何现有的并添加传入的。
    • j.,我没见过railsapi.com。这太棒了!比api.rubyonrails.org好多了。
    • @Tony: 是的,我知道 :] Tks.
    • 很确定你的意思是user.promotions 不是User.promotions。关联的方法在一个实例而不是类上。
    【解决方案3】:

    这也很有用

    User.promotion.build(attr = {})
    

    所以,当您保存用户对象时,促销对象会保存。

    这是

    User.promotion.create(attr = {})
    

    创建您不需要保存的促销或用户模型

    【讨论】:

      【解决方案4】:

      如果您想使用原型 PromotionsController CRUD 设置将用户添加到 Promotion 中,并且您使用 Rails 表单助手,您可以将参数格式化为:

      params = {id: 1, promotion: { id: 1, user_ids: [2] }}
      

      这使您可以保持控制器纤细,例如,您不必向 update 方法添加任何特殊内容。

      class PromotionsController < ApplicationController
      
        def update
          promotion.update(promotion_params)
      
          # simplified error handling
          if promotion.errors.none?
            render json: {message: 'Success'}, status: :ok
          else
            render json: post.errors.full_messages, status: :bad_request
          end
        end
      
        private
      
        def promotions_params
          params.require(:promotion).permit!
        end
      
        def promotion
          @promotion ||= Promotion.find(params[:id])
        end
      end
      

      结果是:

      irb(main)> Promotion.find(1).users
      => #<ActiveRecord::Associations::CollectionProxy [#<User id: 2 ...>]>
      

      【讨论】:

        猜你喜欢
        • 2021-08-14
        • 2010-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多