Rails: 未定义的方法“cover_letter”错误

Rails: undefined method `cover_letter' error

在我的 rails 应用程序中,我有这三个模型 User、Job 和 Job_application 3 之间的关联如下

class Job < ActiveRecord::Base

  has_many :job_applications
  has_many :applicants, :through => :job_applications, :source => :user   

  accepts_nested_attributes_for :job_applications

class JobApplication < ActiveRecord::Base
  belongs_to :user
  belongs_to :job

class User < ActiveRecord::Base
  has_many :job_applications  
  has_many :applied_jobs, :through => :job_applications, :source => :job

在我的工作控制器中我有这个方法,这样用户就可以申请工作

  def apply
    @job = Job.find_by_slug(params[:id])  
    @job_application = JobApplication.new
    @job_application.user_id = current_user.id
    @job_application.job_id = @job.id

    if @job_application.save
      JobMailer.somebody_applied(@job).deliver
      redirect_to job_url(@job)
    else
      render :action => "show"
    end
  end

和我的工作视图页面我有申请方法的代码

<button type="button" id="control_gen_5" data-toggle="modal" data-target="#myModal">
  <span>Envoyer un candidature</span>
</button>

<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close close-this" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <h4 class="modal-title" id="myModalLabel">Apply to <%= @job.job_title %></h4>
      </div>
      <p><%= current_user.full_name%></p>
      <%= form_for @job, :url => apply_job_path(@job), :method => :post, :html => { :multipart => true } do |f| %>
        <%= f.fields_for :job_applications, @job.job_applications.build do |s| %>
          <%= s.hidden_field :user_id %>
          <%= s.hidden_field :job_id %>
          <div class="modal-body">
            <p>
              <div class="form-inputs">
                <%= s.text_area :cover_letter, :input_html => { :rows => 5, :class => 'span12', :value => cookies[:cover_letter] }, :label => false %>
              </div>
            </p>
          </div>
        <% end %>
        <div class="modal-footer">
          <%= f.submit 'Postuler', :class => 'btn btn-info', :name => nil %>
        </div>
      <% end %>
    </div>
  </div>
</div>

我也有这个代码,所以我可以查看谁申请了工作和他们的求职信

</ul>
<% @job.job_applications.each do |job_application| %>
  <li>
    <%= job_application.user.full_name %>
    <%= job_application.cover_letter %>
  </li>
<% end %>
</ul>

但只显示用户全名,不显示求职信。

我已经在我的 rails 控制台中尝试过此代码

j.job_applications.last   where   j = Job.last

这给了我这个

#<JobApplication id: 42, job_id: 24, user_id: 49, cover_letter: nil,  created_at: "2015-04-20 14:22:31", updated_at: "2015-04-20 14:22:31">

任何人都可以帮助知道为什么我在 cover_letter

中得到零

一旦你有

def job_params
  params.require(:job).permit(job_applications_attributes: [:id, :job_id, :user_id, :cover_letter, :resume, :_destroy])
end

在控制器上,您需要将参数设置为新的 JobApplication,例如:

@job_application = JobApplication.new(job_params)

所以看起来 cover_letterJobApplication 的属性,但您从未在控制器的 #apply 操作中将其设置为任何内容。

当前方法:

def apply
  @job = Job.find_by_slug(params[:id])  
  @job_application = JobApplication.new
  @job_application.user_id = current_user.id
  @job_application.job_id = @job.id
  # where are you setting cover_letter? 
  # this is why it does not save
  if @job_application.save
    JobMailer.somebody_applied(@job).deliver
    redirect_to job_url(@job)
  else
    render :action => "show"
  end
end

试试这个:

def apply
  @job = Job.find_by_slug(params[:id])
  #since you are excepting nested attributes through job
  # all you need to do is update the job appropriately using update_attributes      
  if @job.update_attributes(job_application_params)
    JobMailer.somebody_applied(@job).deliver
    redirect_to job_url(@job)
  else
    render :action => "show"
  end
end

private
  def job_application_params
     #since we are building the application off of the job 
     # there is no need for the job_id attribute as this will be 
     # forcefully implied from the parent job
     params.require(:job).permit({job_applications_attributes:[:cover_letter,:user_id]})
  end

你的参数应该通过:

job:{
  #...
  job_application_attributes:[
     "0" =>{
       user_id: ###,
       job_id: ###,
       cover_letter: ""
     }
  ]
}

现在你完全忽略了参数 Hash 中的 cover_letter 这就是它为零的原因。此外,由于我们是从作业构建应用程序,因此根本不需要在 fields_for 部分中指定 job_id。