Ruby on Rails模型方法错误与has_many关联(修订版)

时间:2015-08-27 13:52:00

标签: ruby-on-rails

在我提出问题之前,我将描述我的应用和问题的性质。该应用程序由3个模型组成,所有模型都具有has_many和belongs_to相互关联。但是,我们的问题仅在于记分板模型和团队模型。 以下是所有三种模型的模型文件:

class User < ActiveRecord::Base
    has_many :scoreboards, dependent: :destroy
end

class Scoreboard < ActiveRecord::Base
  belongs_to :user
  has_many :teams
 end

class Team < ActiveRecord::Base
  belongs_to :scoreboard
end

以下代码包含记分板和团队的迁移文件,以备不时之需:

class CreateScoreboards < ActiveRecord::Migration
  def change
    create_table :scoreboards do |t|
      t.string :name_of_scoreboard
      t.string :name_of_organization
      t.string :name_of_activity
      t.references :user, index: true

      t.timestamps null: false
    end
    add_foreign_key :scoreboards, :users
    add_index :scoreboards, [:user_id, :created_at]
  end
end



class CreateTeams < ActiveRecord::Migration
  def change
    create_table :teams do |t|
      t.string :name
      t.integer :win
      t.integer :loss
      t.integer :tie
      t.references :scoreboard, index: true

      t.timestamps null: false
    end
    add_foreign_key :teams, :scoreboards
  end
end

以下是记分板和团队控制器文件。记分板控制器使得与用户模型的关联不是引起关注的原因。

class ScoreboardsController < ApplicationController

 before_action :logged_in_user, only: [:new, :create, :show, :index]
 before_action :correct_user, only: [:destroy, :edit, :update]

 def new
   @scoreboard = Scoreboard.new
 end

 def create
  @scoreboard = current_user.scoreboards.build(scoreboard_params)
  if @scoreboard.save
   flash[:scoreboard] = "Scoreboard created successfully"
   redirect_to scoreboard_path(@scoreboard)
  else
   render 'new'
  end
 end

 def show
  @scoreboard = Scoreboard.find_by_id(params[:id])
 end

private

  def scoreboard_params
   params.require(:scoreboard).permit(:name_of_scoreboard, :name_of_organization, 
                  :name_of_activity, :starts_at, :ends_at, :cities, :states, :country, :picture ) # make sure the name of the parameters match with 
                                     # the exact names written in the scoreboard model.
  end

end

以下是球队控制员:

    def new
     @scoreboard = Scoreboard.find(params[:id]) 
     @team = @scoreboard.teams.build
   end

   def create
     @scoreboard = Scoreboard.find(params[:id])
     @team = @scoreboard.teams.build(team_params)
     if @team.save
       flash[:success] = "Saved Successfully"
       redirect_to scoreboard_url(@team.scoreboard_id) #redirecting it to the scoreboard url associated with that team
     else
       render 'new'
     end
   end

团队成员

<div class="team-contain">
   <%= form_for(@team) do |f| %>

         <%= render 'shared/error_messages', object: f.object %>

         <%= hidden_field_tag :scoreboard_id, @scoreboard.id %>

         <%= f.label :name  %>
         <%= f.text_field :name, class: "form-control"  %>

         <%= f.label :win %>
         <%= f.number_field :win, class: "form-control" %>

         <%= f.label :loss %>
         <%= f.number_field :loss, class: "form-control" %>

         <%= f.label :tie %>
         <%= f.number_field :tie, class: "form-control" %>


         <%= f.submit "Create", class: "btn btn-primary" %>

         <% end %>
</div>

我们已将记分牌模型与团队模型相关联,其中记分板具有多个团队并且每个团队属于记分板。一旦编写了该关联,记分板类就会自动拥有可用于构建记分板和团队之间关系的方法。如上面的团队控制器所示,创建操作中使用的方法是@team = @scoreboard.teams.build(team_params)。此方法应在记分板和团队之间创建has_many关联。但是,问题是我收到错误"Undefined method "teams" for nil class"。我不知道为什么我得到这个,因为一旦建立关联,@scoreboard.teams.build方法应该自动可用。此外,班级不是零。记分板类在模型中定义。我真的不确定为什么我会收到这个错误。我已经阅读了有关ruby on rails的关联指南。基于此,此代码应该可行。我不确定我错过了什么。

此外,我们如何知道团队与该特定记分牌相关。例如,用户可以拥有许多记分牌。我们如何确保该特定记分板的主键是团队的外键。基本上,我们如何确保每个团队“1”与特定记分板“A”相关联而不是记分板“B”。是否可以找到记分板by_id并将其保存为@relevant_scoreboard或者协会自动处理此事。对这一点的任何澄清都会非常有帮助。 我希望我已经清楚地解决了这个问题。任何帮助将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

  

如上面的团队控制器中所见,create中使用的方法   行动是“@team = @ scoreboard.teams.build(team_params)”。这种方法   应该在记分板和团队之间创建一个has_many关联。   但是,问题是我得到一个错误“Undefined method”团队“   为零级“

您尚未初始化@scoreboard,因此@team = @scoreboard.teams.build(team_params)不起作用。像@scoreboard = Scoreboard.find(params[:scoreboard_id])一样定义它可以解决您的问题。

  

另外,我们如何知道团队与特定团队有关   记分牌。例如,用户可以拥有许多记分牌。怎么做   我们确保该特定记分牌的主键是   团队的外键

使用scoreboard_id表格中的 foreign_key teams,您可以致电@scoreboard.teams,获取与特定记分板相关联的团队。

例如,假设您有以下代码

@scoreboard = Scoreboard.find(1)
@scoreboard.teams #will return the teams associated with it.

另外,我建议您查看这些guides,以便更好地了解幕后的工作原理。