嵌套表单复合体has_many:through [英] Nested Form complex has_many :through

查看:75
本文介绍了嵌套表单复合体has_many:through的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个复杂的has_many通过关系,用户可以通过应用程序向Jobs申请.

I have a complex has_many through relationship, where Users can apply to Jobs through Applications.

在创建每个作业时,管理员会选择某些问题.在Applications#new期间,当用户正在申请新工作时,我也希望用户回答问题才能申请.

When creating each job, the admin chooses certain questions. During Applications#new, when the user is applying to a new job, I'd also like the user to answer the questions in order to apply.

为此,我按如下方式设置模型:

To do this, I set up my models like so:

Job
has many users through application
has many questions 

Users
has_many jobs through application 

Application
    belongs_to :user
    belongs_to :job
    has_many :answers

Question
    belongs_to :job
    has_one :answer

Answer
    belongs_to :application
    belongs_to :question

我现在有一个应用程序控制器.

I now have an application controller.

在这里我被困住了.如何使用户能够在Applications#new视图上回答问题?

这是到目前为止的样子->

This is what it looks like so far ->

应用程序控制器

class ApplicationsController < ApplicationController

 def new 
    @application = Application.new() 
    if params[:job_id] # Applications will only be built by clicking on a specific job, which transfers the id of that job 
      @application.job_id = params[:job_id]
      @application.user_id = current_user.id
    else
      redirect_to root_url, :notice => "Something went wrong. Please contact us and mention this"
    end
    @job = Job.find(@application.job_id)
    @user = current_user

 end


end

控制器实质上是对其进行设置的,以便当用户单击提交"时,应用程序将具有用户ID和工作ID,从而有效地建立连接

Applications#new视图

<%= form @application do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <% @job.questions.each do |question| %>
  <h4><%= question.content %></h4>
     #What do I do here to allow the user to answer the question?
  <% end %>
   <%= f.submit "Submit the application", class: "button" %>
<% end %>

应用程序模型

# == Schema Information
#
# Table name: applications
#
#  id         :integer          not null, primary key
#  user_id    :integer
#  job_id     :integer
#  created_at :datetime
#  updated_at :datetime
#

class Application < ActiveRecord::Base
    belongs_to :job
    belongs_to :user
    validates :job_id, presence: true 
    validates :user_id, presence: true 
    has_many :answers
    accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end

推荐答案

困难的问题....

这可能行不通(特别是关联和保存参数),但是我花了一些时间考虑一下,希望能为您指明正确的方向:

This might not work (specifically the associations & the save params), but I spent some time thinking about it, so hopefully will point you in the right direction:

结构

我将按以下方式创建您的关联:

I would create your associations as follows:

#app/models/job.rb
Class Job < ActiveRecord::Base
    has_many :applications
    has_many :questions
end

#app/models/application.rb
Class Application < ActiveRecord::Base
    belongs_to :user
    belongs_to :job

    has_many :questions, class_name: "Question"
    has_many :answers, class_name: "ApplicationAnswer"

    accepts_nested_attributes_for :answers
end

#app/models/question.rb
Class Question < ActiveRecord::Base
    belongs_to :job
end

#app/models/application_answer.rb
Class ApplicationAnswer < ActiveRecord::Base
    belongs_to :application
    belongs_to :question
end


模式

jobs
id | name | info | created_at | updated_at

applications
id | user_id | job_id | created_at | updated_at

questions
id | job_id | created_at | updated_at

answers
id | application_id | question_id | answer_info | created_at | updated_at 


路线

我将创建嵌套路由,以便您只能为特定作业创建应用程序:

I would create nested routes so that you can only create an application for a specific job:

#config/routes.rb
resources :jobs do 
     resources :applications
end


控制器

#app/controllers/applications_controller.rb
def new
    @job = Job.find(params[:job_id])

    @application = Application.new
    @job.questions.count.times do { @application.answers.build } #-> gives you fields equivalent for number of questions per job 
end


表格

使用 accepts_nested_attributes_for ,您将能够如下创建表单(使用此想法进行升级):

#app/views/applications/new.html.erb
<%= form_for @application do |f| %>
    <% @job.questions.each_with_index do |question| %>
         <%= f.fields_for :answers, question do |question_field| %>
              <%= question_field.label_for :answer, question.text %>
              <%= question_field.text_field :answer %>
              <%= question_field.hidden_field :question_id, question.id %>
         <% end %>
    <% end %>
<% end %>


保存

#app/controllers/applications_controller.rb
def create
    @application = Application.new(application_params)
    @application.save
end

private
def application_params
    params.require(:application).permit(:job_id, :user_id, answers_attributes:[:answer, :question_id]).merge(user_id: current_user.id)
end

我认为您的问题既是系统结构问题,又是功能问题.要了解嵌套模型的提交过程,您可以受益于观看此Railscast

I think your issue is as much a system structure problem as a functional issue. To understand the nested model submission process, you'd benefit from watching this Railscast

这篇关于嵌套表单复合体has_many:through的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆