【问题标题】:Issue with join table and has_many through association in Rails 4通过 Rails 4 中的关联出现连接表和 has_many 问题
【发布时间】:2015-11-17 08:07:38
【问题描述】:

伙计们,这是我的数据库结构。 AccountGrade.rb MODEL,它是一个帐户和等级模型的连接表

class AccountGrade < ActiveRecord::Base
  belongs_to :account
  belongs_to :grade
  attr_accessor :grade
  attr_accessor :section
end

我的帐户.rb 模型

class Account < ActiveRecord::Base
  has_many :grades, :through => :account_grades
  has_many :account_grades
  belongs_to :user
  validates :school_name,:line_1,:city,:state,:country,:pincode,:phone_number, :presence => true
  validates :pincode,:phone_number,numericality: { only_integer: true }
end

我的成绩.rb 模型

class Grade < ActiveRecord::Base
  has_many :accounts, :through => :account_grades
  has_many :account_grades
  attr_accessor :account_grades
end

我的成绩控制器.rb

class GradesController < ApplicationController
  def index
    @grades = Grade.all
    render json: {
      Grades:@grades
    }.to_json
  end

  def add_class_sections
    # unless params[:section]
      @account_grades = AccountGrade.new class_sections_params
      puts "Grades are #{@account_grades}"

      @grades.each do |grade|
        @account_grades = grade
        puts grade
        puts @account_grades
      end
    # end #unless ends here
  end #function add_class_sections ends here


  private

    def class_sections_params
      params.permit!
      # params.require(:gardes).permit(:section)#, :email, :password, :salt, :encrypted_password)
    end

end #class ends here

我的终端跟踪中出现以下错误。

Started POST "/add_classes?grade_id[0]=1&section[0]=2&grade_id[1]=2&section[1]=1&grade_id[2]=3&section[2]=1" for 127.0.0.1 at 2015-11-17 12:43:47 +0530
  ActiveRecord::SchemaMigration Load (0.1ms)  SELECT `schema_migrations`.* FROM `schema_migrations`
Processing by GradesController#add_class_sections as */*
  Parameters: {"grade_id"=>{"0"=>"1", "1"=>"2", "2"=>"3"}, "section"=>{"0"=>"2", "1"=>"1", "2"=>"1"}}
Completed 500 Internal Server Error in 10ms (ActiveRecord: 0.8ms)

ActiveRecord::UnknownAttributeError (unknown attribute 'controller' for AccountGrade.):
  app/controllers/grades_controller.rb:11:in `add_class_sections'


  Rendered /home/anjan/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_source.erb (11.0ms)
  Rendered /home/anjan/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (1.7ms)
  Rendered /home/anjan/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (0.9ms)
  Rendered /home/anjan/.rvm/gems/ruby-2.2.1/gems/actionpack-4.2.4/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (24.8ms)

【问题讨论】:

  • 嘿,你的哈希值,即新 AccountGrade 的参数结构是错误的,因为你有像 controlleraction 这样的内容属性,这里不需要,所以它会给你错误
  • 嗨@VishalJAIN,谢谢。你能详细说明一下吗,因为我是一个铁轨菜鸟,我不太清楚我穿在哪里?
  • 问个简单的问题,你为什么要设置一个虚拟属性attr_accessor :grade 而你有belongs_to :grade
  • 仅当属性未出现在您的数据库中时
  • @RichPeck 非常感谢您的回答帮助很大。玩了一下,我就可以让它工作了。再次感谢丰富。 :D

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord strong-parameters


【解决方案1】:

哇,你的代码有很多问题。

不管你的推理如何,这就是你应该让它工作的方式......


#app/controllers/grades_controller.rb
class GradesController < ApplicationController
    def index
      @grades = Grade.all
      respond_to do |format|
         format.json { render json: @grades.to_json }
         format.html
      end
    end

    def create
      @account_grades = AccountGrade.new class_sections_params
      redirect_to @account.grades if @account_grades.save
    end

  private

    def sections_params
      params.require(:grades).permit(:section)
    end
end

如果您让这段代码正常工作,您将更容易理解它为什么要寻找 controller 属性(这是一个奇怪的错误)。

您还应该了解 Rails 中的几个约定:

  1. 不要在控制器中使用puts - 你有Rails.logger.info() 可以输出到你的控制台。
  2. 让你的动作保持安静——尽管这可能——而且经常被——破坏,Rails 控制器的安静本质应该是最重要的惯例。不要打电话给add_class_section,除非你真的必须——相反,你应该根据需要考虑使用newcreate方法。

--

另外,删除所有 attr_accessor 引用,尤其是与任何关联名称冲突的引用。

attr_accessor 基本上为您的模型声明了新的getter/setter 方法。如果这些方法覆盖了任何关系,它们实际上会阻止它们工作。

您不需要attr_accessor,除非您想创建一个半持久属性(即不保存到数据库的IE)。 attr_accessor 在 Rails 中最常见的用法是创建 virtual attributes

【讨论】:

    【解决方案2】:

    这就是我想要实现的。欢迎任何关于重构或改进以下代码的建议。

    class GradesController < ApplicationController
      before_filter :authenticate, only: [:create]
    
        def index
          @grades = Grade.all
          render json: @grades.to_json
        end
    
        def create
          @section_name_counter = 0
          @section_names=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S",
                         "T","U","V","W","X","Y","Z"]
          @account_grades = AccountGrade.new #sections_params
          @account_grades.grade_id = params[:grade_id]
          @account_grades.account_id = params[:account_id]
          @account_grades.save!
    
          while @section_name_counter < params[:section].to_i do
            @section = Section.new
            @section.account_grade_id = @account_grades.id
            @section.name = @section_names[@section_name_counter]
            @section.save!
            @section_name_counter += 1
          end
          render json: @account_grades if @section.save
        end
    
      private
    
        def sections_params
          params.require(:grade_id).permit(:section,:account_id)
        end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-16
      • 2014-03-25
      • 2010-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多