Question

I create 2 model with scaffold:

  1. problem
  2. reporter

I want create 1 reporter for each problem and use before_create for create reporter.

I generate reporter_id by integer type in problems table in database. The below code show the problem and reporter action and model :

problem.rb

class Problem < ActiveRecord::Base
  has_one :reporter
  before_create :build_reporter
end

reporter.rb

class Reporter < ActiveRecord::Base

  belongs_to :problem

end

problems_controller.rb

class ProblemsController < ApplicationController

  before_action :set_problem, only: [:show, :edit, :update, :destroy]

  def index
    @problems = Problem.all
  end

  def show
  end

  def new
    @problem = Problem.new
  end

  def edit
  end

  def create
    @problem = Problem.new(problem_params)

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

  def update
    respond_to do |format|
      if @problem.update(problem_params)
        format.html { redirect_to @problem, notice: 'Problem was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @problem.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @problem.destroy
    respond_to do |format|
      format.html { redirect_to problems_url }
      format.json { head :no_content }
    end
  end

private def set_problem @problem = Problem.find(params[:id]) end

def problem_params
  params.require(:problem).permit(:reporter_id, :describe_id, :datetime, :trace_code, :status)
end

end

reporter_controller.rb

class ReportersController < ApplicationController
  before_action :set_reporter, only: [:show, :edit, :update, :destroy]

  def index
    @reporters = Reporter.all
  end

  def show
  end

  def new
    @reporter = Reporter.new
  end

  def edit
  end

  def update
    respond_to do |format|
      if @reporter.update(reporter_params)
        format.html { redirect_to @reporter, notice: 'Reporter was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @reporter.errors, status: :unprocessable_entity }
      end
    end
  end

  def destroy
    @reporter.destroy
    respond_to do |format|
      format.html { redirect_to reporters_url }
      format.json { head :no_content }
    end
  end

  private
    def set_reporter
      @reporter = Reporter.find(params[:id])
    end

    def reporter_params
      params.require(:reporter).permit(:user_name, :gomrok_name, :phone_number)
    end
end

When I choose new problems button in localhost:3000/problems, the textfields are show, but when complete textfield and choose create problem button, I get this error:

ActiveRecord::UnknownAttributeError in ProblemsController#create 


unknown attribute: problem_id
Extracted source (around line #31):   


respond_to do |format|
  if @problem.save
    format.html { redirect_to @problem, notice: 'Problem was successfully created.' }
    format.json { render action: 'show', status: :created, location: @problem }
  else

what is the problem_id ?!

I didn't use this.

and I want set the reporter ID in problems table in database; how can I create the reporter with before_create or after_create and save the reporter_id in problem table?

Was it helpful?

Solution

You have setup the relationship incorrectly. What you have is a reporter_id column in problems table. In a 1-1 Relationship foreign_key is created on the belongs_to side. So, your code should look like:

class Problem < ActiveRecord::Base
  belongs_to :reporter
end

class Reporter < ActiveRecord::Base    
  has_one :problem   
  before_create :build_problem
end
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top