使用表格Rails 5

时间:2018-10-23 23:47:26

标签: ruby-on-rails ruby activerecord ruby-on-rails-5 friendly-id

我检查了可用的各种解决方案,但似乎都没有解决我的项目遇到的问题。我试图允许用户通过EmployerReview模型为雇主创建评论。当我将employer_id传递到form_for中的employer_reviews_controller时,它声称没有ID找不到雇主。该ID与@employer实例变量一起传递。我不明白为什么它不起作用。最后,我使用的是friendly_id,它显示在新雇主审核地址 employer_reviews / new.bryers 的末尾。如何阻止此错误的发生?

模式

create_table "employer_reviews", force: :cascade do |t|
    t.text "review_body"
    t.string "review_title"
    t.bigint "user_id"
    t.bigint "employer_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["employer_id"], name: "index_employer_reviews_on_employer_id"
    t.index ["user_id"], name: "index_employer_reviews_on_user_id"
  end

employer_review.rb

class EmployerReview < ApplicationRecord
  belongs_to :employer
  belongs_to :user
end

user.rb

class User < ApplicationRecord
  has_many :employer_reviews, dependent: :destroy
end

employer.rb

class Employer < ApplicationRecord
  extend FriendlyId
  friendly_id :username, use: [:slugged, :finders]
  has_many :employer_reviews, dependent: :destroy
end

employers_controller.rb

class EmployersController < ApplicationController
  before_action :set_employer, only: [:show]

  def show
    impressionist(@employer)
  end


  private

  def set_employer
    @employer = Employer.find(params[:id])
  end
end

employer_reviews_controller.rb

class EmployerReviewsController < ApplicationController
  before_action :set_employer_review, only: [:show, :edit, :update, :destroy]
  before_action :set_employer
  before_action :authenticate_user!

  # GET /employer_reviews/1
  # GET /employer_reviews/1.json
  def show
  end

  # GET /employer_reviews/new
  def new
    @employer_review = EmployerReview.new
  end

  # GET /employer_reviews/1/edit
  def edit
  end

  # POST /employer_reviews
  # POST /employer_reviews.json
  def create
    @employer_review = EmployerReview.new(employer_review_params)
    @employer_review.user_id = current_user.id
    @employer_review.employer_id = @employer_review.id

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

  # PATCH/PUT /employer_reviews/1
  # PATCH/PUT /employer_reviews/1.json
  def update
    respond_to do |format|
      if @employer_review.update(employer_review_params)
        format.html {redirect_to @employer_review, notice: 'Employer review was successfully updated.'}
        format.json {render :show, status: :ok, location: @employer_review}
      else
        format.html {render :edit}
        format.json {render json: @employer_review.errors, status: :unprocessable_entity}
      end
    end
  end

  # DELETE /employer_reviews/1
  # DELETE /employer_reviews/1.json
  def destroy
    @employer_review.destroy
    respond_to do |format|
      format.html {redirect_to employer_reviews_url, notice: 'Employer review was successfully destroyed.'}
      format.json {head :no_content}
    end
  end

  private

  # Use callbacks to share common setup or constraints between actions.
  def set_employer_review
    @employer_review = EmployerReview.find(params[:id])
  end

  def set_employer
    @employer = Employer.find(params[:employer_id])
  end

  # Never trust parameters from the scary internet, only allow the white list through.
  def employer_review_params
    params.require(:employer_review).permit([:review_title, :review_body])
  end
end

雇主show.html.erb

<%= link_to 'Write a review', new_employer_review_path(@employer) %>

routes.rb

resources :employers
resources :employer_reviews

评论表格

<%= simple_form_for([@employer, @employer_review]) do |f| %>
  <%= f.error_notification %>
  <div class="form-group">
    <label>Review Title</label>
    <%= f.input :review_title, class: 'form-control', placeholder: 'Add a review title' %>
  </div>
  <div class="form-group">
    <label>Tell us about your experience</label>
    <%= f.input :review_body, :as => :text, :input_html => { 'rows' => 5, 'cols' => 10 }, class: 'form-control', placeholder: 'Add a review title' %>
  </div>

  <div class="form-actions">
    <%= f.button :submit %>
  </div>
<% end %>

更新1: 当我在simple_form中同时使用@employer_review和@employer时,出现以下错误。

ActionView::Template::Error (undefined method `model_name' for nil:NilClass):
    1: <%= simple_form_for([@employer_review, @employer]) do |f| %>
    2:   <%= f.error_notification %>
    3:   <div class="form-group">
    4:     <label>Review Title</label>

app/views/employer_reviews/_form.html.erb:1:in `_app_views_employer_reviews__form_html_erb__154747394_155744960'
app/views/employer_reviews/new.html.erb:3:in `_app_views_employer_reviews_new_html_erb__376973310_155859880'
Processing by ExceptionHandler::ExceptionsController#show as HTML
  Parameters: {"employer_id"=>"test_employer"}
Completed 500 Internal Server Error in 404ms (ActiveRecord: 0.0ms)

1 个答案:

答案 0 :(得分:2)

您的employersemployer_reviews资源未嵌套。这意味着employer_id中的EmployerReviewsController参数是nil(如果未在查询字符串中显式设置)。调用set_employer过滤器无效,并且@employer实例变量为nil。这就是simple_form无法找到该雇主(没有ID)的原因。

您要么必须将{{1}的employer_reviews转到nested resource,要么从employers中删除@employer变量,而EmployerReviewsController仅用于{ {1}}。