简体   繁体   English

在has_many Through关系中为Through设置Rails Controller

[英]Setting up Rails Controller for the through in has_many through relationship

I am creating a rails web app with a many-to-many through model. 我正在创建一个具有多对多模型的Rails Web应用程序。 The application is to allow users to populate their dashboard with a number of pre-defined "widgets". 该应用程序允许用户使用许多预定义的“小部件”填充其仪表板。 So I have a table of users (created and managed by devise) and a table of widgets. 因此,我有一个用户表(由devise创建和管理)和一个小部件表。 All good. 都好。 So to manage the through bit, I have a table of "subscriptons". 因此,要管理直通位,我有一个“下标”表。 Here are my models: 这是我的模型:

class Subscription < ActiveRecord::Base
  belongs_to :user
  belongs_to :widget
  validates_uniqueness_of :user_id, scope: :widget_id
end

class User < ActiveRecord::Base
  has_many :subscriptions
  has_many :widgets, through: :subscriptions
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

class Widget < ActiveRecord::Base
  has_many :subscriptions
  has_many :users, through: :subscriptions
end

However, I don't really understand how to create the subscriptions. 但是,我不太了解如何创建订阅。 I would ideally like the create form to just have a selector to choose from all available widgets and then user the current user:id but I am not sure how this would work, here is my controller: 理想情况下,我希望创建表单仅具有一个选择器以从所有可用的小部件中进行选择,然后使用当前user:id但是我不确定这将如何工作,这是我的控制器:

  def new
    @subscription = Subscription.new
  end

  def create
    @user = current_user
    @subscription = @user.subscriptions.build(subscription_params)

    respond_to do |format|
      if @subscription.save
        format.html { redirect_to @subscription, notice: 'subscription was successfully created.' }
        format.json { render :show, status: :created, location: @subscription }
      else
        format.html { render :new }
        format.json { render json: @subscription.errors, status: :unprocessable_entity }
      end
    end
  end

I would really appreciate a nudge in the right direction, as I can't understand how this is done from the official docs and haven't found any good tutorials relating to this. 我非常希望能朝正确的方向前进,因为我无法从官方文档中了解如何完成此操作,也没有找到与此相关的任何优秀教程。

Assuming you don't have any other attributes on subscriptions you can use the widget_ids= method that your has_many creates on user 假设您在订阅上没有任何其他属性,则可以使用has_many在用户上创建的widget_ids=方法

Controller 控制者

class UserSubscriptionsController
  def edit
    @user = current_user
  end

  def update
    @user = current_user
    if @user.update(user_subscription_params)
      redirect_to @user, notice: "Subscriptions updated"
    else
      render :edit
    end
  end

  private

  def user_subscription_params
    params.require(:user).permit(widget_ids: [])
  end
end

View 视图

<%= form_for @user, url: user_subscription_path, method: :patch do |f| %>
  <%= f.collection_check_boxes :widget_ids, Widget.all, :id, :name %>
  <%= f.submit %>
<% end %>

The routes in my example would have 在我的示例中,路线

resource :user_subscription, only: [:edit, :update]

But obviously you can amend based on what you want your routes to be. 但是显然,您可以根据自己的路线进行修改。 Rails will automatically create the subscriptions when updating the user. 更新用户时,Rails会自动创建订阅。

You could instead just use the collection_check_boxes when editing a user normally if you wanted. 相反,您可以根据需要在正常编辑用户时仅使用collection_check_boxes There is also collection_select 还有collection_select

Docs 文件

You can save data like this using subscription form. 您可以使用订阅表单保存此类数据。

  = form_for @subscription do |f|
   = f.select :widget_id, options_from_collection_for_select(Widget.all, "id", "title"), {}, {:class => "form-control select" }
   = f.hidden_field :user_id, :value => current_user.id
   #other subscription fields
   = f.submit

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM