在 rails user-submissions-contest 中保存用户 ID 有很多通过模型

saving user id in rails user-submissions-contest has many through model

如何配置 rails 控制器,以便我可以让用户 post 在任何比赛中提交。当他们 post 他们的用户 ID 和比赛 ID 应该自动附加到提交中。

我知道我能做到:

  1. User.first.contests.create => 让用户创建比赛
  2. Contest.first.submissions.create => 在比赛中创建提交(不link发给用户)
  3. User.first.submissions.create => 创建 link 提交给用户但不提交给比赛
  4. 我做不到 User.first.Contest.last.submissions.create => 我想 link 提交一个竞赛 提交。

有什么优雅的方法可以解决这个问题吗?

提交控制器如下所示:

class SubmissionsController < ApplicationController
  before_action :set_submission, only: [:show, :edit, :update, :destroy]

  # the current user can only edit, update or destroy if the id of the pin matches the id the user is linked with.
  before_action :correct_user, only: [:edit, :update, :destroy]
  # the user has to authenticate for every action except index and show.
  before_action :authenticate_user!, except: [:index, :show]


  respond_to :html

  def index
    @title = t('submissions.index.title')

    @submissions = Submission.all
    respond_with(@submissions)
  end

  def show
    @title = t('submissions.show.title')

    respond_with(@submission)
  end

  def new
    @title = t('submissions.new.title')

    @submission = Submission.new
    respond_with(@submission)
  end

  def edit
    @title = t('submissions.edit.title')

  end

  def create
    @title = t('submissions.create.title')

    @submission = Submission.new(submission_params)
    @submission.save
    respond_with(@submission)
  end

  def update
    @title = t('submissions.update.title')

    @submission.update(submission_params)
    respond_with(@submission)
  end

  def destroy
    @title = t('submissions.destroy.title')

    @submission.destroy
    respond_with(@submission)
  end

  private
    def set_submission
      @submission = Submission.find(params[:id])
    end

    def submission_params
      arams.require(:submission).permit(:reps, :weight, :user_id)
    end

    def correct_user
      @submission = current_user.submissions.find_by(id: params[:id])
      redirect_to submissions_path, notice: t('submissions.controller.correct_user') if @submission.nil?
    end

end

我有以下型号:

class Contest < ActiveRecord::Base
  has_many :submissions
  has_many :users, through: :submissions

class Submission < ActiveRecord::Base
  belongs_to :user
  belongs_to :contest

class User < ActiveRecord::Base
  has_many :submissions
  has_many :contests, through: :submissions

您可以在 SubmissionsController#create

中使用 @submission = current_user.submissions.new(submission_params)@contest = Contest.find(params[:contest_id])

编辑:我添加了一些关于在 submissions table.[=24= 中添加对 contest_id 的引用的详细信息]

我发现在 Rails(实际上,任何关系数据库)中将相关事物联系在一起的最好方法是在子 table 中添加对父 [=16] 的引用=].您可以通过 Rails.

中的迁移来执行此操作

rails g migration AddContestToSubmission contest:references

并修改在您的 db/migrate/<datetime>_add_contest_to_submission 中生成的迁移文件,使其看起来类似于:

class AddContestToSubmission < ActiveRecord::Migration
  def change
    add_reference :submissions, :contest, index: true
  end
end

然后继续看看你的 submissions table 在你的 schema.rb 中。您应该注意到类似 t.integer "contest_id" 的内容 如果您希望将提交绑定到一个 user.

,您可能还应该在迁移中添加 user_id

我觉得你把事情搞得有点复杂了。

提交在竞赛中发布,提交需要知道user_id。

<%= simple_form_for :submission, url: contest_submissions_path(contest) do |f| %>
                  ...
    <%= f.submit 'Submit', class: "button" %>
<% end %>

以及您提交的 CREATE 方法

class SubmissionsController < ApplicationController

  def create
    @contest = Contest.find(params[:contest_id])
    @submission = @contest.submissions.new(submission_params)
    @submissions.user = current_user
    .....
  end

奇迹发生在 @submissions.user = current_user 如果您使用的是 Devise,很容易在控制器中的 current_user.id 任何地方传递,就像我刚刚在提交控制器中所做的那样。