has_many通过创建现有模型的关系

时间:2015-07-06 16:11:14

标签: ruby-on-rails ruby-on-rails-4 activerecord has-many-through nested-resources

我有一个市场,我的用户可以创建计划,他们的客户可以加入他们。所以我有一个Plan模型和一个Customer模型。最终目标是订阅客户到计划,所以我创建了一个订阅模型和一个has_many:通过关联,但我需要一些帮助才能使创建正常工作。在订阅能够发生时,计划和客户已经存在,所以我不需要担心在订阅#create时创建计划或客户,我只需要担心加入现有的计划。

我现在所处的位置是我在订阅模型上进行创建,但它并没有与正确的客户相关联。我需要为我订阅该计划的每个客户创建一个订阅模型,并且我正在使用多选标签。

我正在使用has_many:通过因为计划有很多客户,但客户也可以有很多计划。

如果有任何不清楚的地方,请告诉我。我试图尽可能简明扼要地解释。

计划模型

class Plan < ActiveRecord::Base
    has_many :subscriptions
    has_many :customers, through: :subscriptions
end

客户模式

class Customer < ActiveRecord::Base
    has_many :subscriptions
    has_many :plans, through: :subscriptions, dependent: :delete_all
end

订阅模式

class Subscription < ActiveRecord::Base
    belongs_to :plan
    belongs_to :customer
end

的routes.rb

  resources :customers
  resources :plans do
    resources :subscriptions
  end

订阅控制器

class SubscriptionsController < ApplicationController

    def new
        @user = current_user
        @company = @user.company
        @plan = Plan.find(params[:plan_id])
        @subscription = Subscription.new
    end

    def create
        if @subscription = Subscription.create(plan_id: params[:subscription][:plan_id] )
            @subscription.customer_id = params[:subscription][:customer_id]
            @subscription.save
            flash[:success] = "Successfully Added Customers to Plan"
            redirect_to plan_path(params[:subscription][:plan_id])
        else
            flash[:danger] = "There was a problem adding your customers to this plan"
            render :new
        end
    end
    private

    def subscription_params
        params.require(:subscription).permit(:customer_id, :plan_id, :stripe_subscription_id)
    end
end

表格:

    <%= form_for [@plan, @subscription] do |f| %>
    <%= f.hidden_field :plan_id, value: @plan.id %>
    <div class="row">
        <div class="col-md-6">
            <%= f.select :customer_id, options_from_collection_for_select(@company.customers, 'id', 'customer_name', @plan.customers), {}, multiple: true, style: "width: 50%;" %><br />
        </div>
        <div class="col-md-12">
            <%= f.submit "Add Customer To Plan", class: "btn btn-success pull-right" %>
        </div>
    </div>
    <% end %>

params:

{"utf8"=>"✓",
 "authenticity_token"=>"###",
 "subscription"=>{"plan_id"=>"5", "customer_id"=>["", "153", "155"]},
 "commit"=>"Add Customer To Plan",
 "action"=>"create",
 "controller"=>"subscriptions",
 "plan_id"=>"5"}

1 个答案:

答案 0 :(得分:0)

params [:subscription] [:customer_id]是一个数组:

 "subscription"=>{"plan_id"=>"5", "customer_id"=>["", "153", "155"]},

您是否真的尝试在此计划与此阵列中的每个客户之间设置订阅?如果是这样,请尝试调用@plan对象的更新方法,将其传递到params[:plan][:customer_ids](注意s)

编辑:

当我说“通过params[:plan][:customer_ids]中的ID时,我希望你做更新的标准控制器行为,这是

@plan = Plan.find(params[:plan_id])
@plan.update_attributes(params[:plan])

如果params = {:plan => {:customer_ids => [1,2,3]}},则上述代码将执行此操作:

@plan.update_attributes({:customer_ids => [1,2,3]})

就像说

@plan.customer_ids = [1,2,3]
@plan.save

设置关联时,可以在对象上调用许多方法。其中一个是<association>_ids,在这种情况下是customer_ids,这是一种设置关联的方式:当您保存时,它将使@plan与客户1,2和&之间建立关联。 3。

你这样做:

@plan.customers << params[:plan][:customer_ids]

将客户记录与ID混合在一起。如果您要使用push,又称<<,则需要推送客户对象,而不是ID。仅使用customer_ids =是一种更快捷,更简单的方法。