【问题标题】:Rails: undefined method `cover_letter' errorRails:未定义的方法“cover_letter”错误
【发布时间】:2015-04-21 01:29:59
【问题描述】:

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

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

在我的工作视图页面中,我有这个 apply 方法的代码

<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 没有得到任何结果

【问题讨论】:

  • 提交表单时可以发布日志吗?

标签: ruby-on-rails ruby ruby-on-rails-4 nested-attributes


【解决方案1】:

所以看起来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。

【讨论】:

  • 不使用强参数我收到此错误 ActiveModel::ForbiddenAttributesError 第一个解决方案还为 JobApplication 引发此错误未知属性“job_applications_attributes”。
  • @rocki 您没有指定 rails 版本,所以我添加了两者,因为您收到该错误,您显然正在使用 strong_parameters 我将更新答案。此外,由于我们排除了嵌套属性,您只需更新作业,请参阅我上面的修订。
  • 这对我有用,但实际上我在 中遇到了用户 full_name undefined method `full_name' for nil:NilClass 的另一个错误
  • @rocki 请发布您的参数,因为如果不知道为什么它没有设置user_id,我无法提供任何帮助。您收到的错误是因为 job_application.usernil 因此没有 full_name 方法。我也没有看到你在表格中设置user_id。这应该来自哪里? current_user 可能吗?如果是这样,请建议,我会帮你重写表格
  • 我可以用这个得到应聘者姓名
  • 我不知道这个最好的解决方案是否可以请你为我的申请表提出一个更好的解决方案
【解决方案2】:

一旦你有

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_letter 设置为job_application。我不记得到底是如何在参数上设置嵌套属性的。检查参数以确认。
  • 我已经这样做了 def job_params params.require(:job).permit(job_applications_attributes: [:id, :job_id, :user_id, :cover_letter, :resume, :_destroy])
  • 好。现在您可以将允许的属性设置为 job_application:@job_application = JobApplication.new(job_params)
  • 我已经尝试过了,它给了我 JobApplication 的未知属性“job_applications_attributes”这个错误。
  • @rocki 这是因为嵌套参数的语法是错误的,您需要将它们包装在一个哈希中,就像params.require(:job).permit({job_applications_attributes: [:id, :job_id, :user_id, :cover_letter, :resume, :_destroy]}) 这样strong_parameters 知道这些资源会响应给定的方法可接受的标量值。虽然请注意,您目前根本没有发送resume,甚至_destroy 根据您的实现是有问题的,但我看不到该字段的生成位置。
猜你喜欢
相关资源
最近更新 更多
热门标签