调用与另一个类关联的方法时丢失的方法(:belongs_to relationship)

时间:2014-11-08 02:05:37

标签: ruby-on-rails jointable nomethoderror table-relationships

我们尝试了has_manybelongs_to relationship:我们创建了一个类ArticleCategory - 属于Article。文章有很多article_categories。 ArticleCategory有一个属性 - sport:string

我们无法调用Article.last.article_categories,因为它会返回此错误消息:

NoMethodError: undefined method

以下是我们的相关代码:

ArticleCategories控制器

class ArticleCategoriesController < ApplicationController
  before_action :set_article_category, only: [:show, :edit, :update, :destroy]

  def index
    @article_categories = ArticleCategory.all
    respond_with(@article_categories)
  end

  def show
    respond_with(@article_category)
  end

  def new
    @article_category = ArticleCategory.new
    respond_with(@article_category)
  end

  def edit
  end

  def create
    @article = Article.find(params[:article_id])
    @article_category = @article.article_categories.build(article_category_params)



    # @article_category = ArticleCategory.new(article_category_params)
    @article_category.save
    respond_with(@article_category)
  end

  def update
    @article_category.update(article_category_params)
    respond_with(@article_category)
  end

  def destroy
    @article_category.destroy
    respond_with(@article_category)
  end

  private
    def set_article_category
      @article_category = ArticleCategory.find(params[:id])
    end

    def article_category_params
      params.require(:article_category).permit(:sport)
    end
end

ArticleCategories模型

class ArticleCategory < ActiveRecord::Base
    belongs_to :article
end

文章控制器

class ArticlesController < ApplicationController

  load_and_authorize_resource
  skip_authorize_resource :only => [:index, :show]

def new
    @article = Article.new
end

def create
    @article = Article.new(article_params)
#  authorize! :create, @article

    if @article.save
    #send email to referral email
    all_users = User.all
    all_users.each do |user|
      ArticleMailer.article_confirmation(user,@article).deliver
   end 
   redirect_to @article
    else
     render 'new'
    end
end

def show
    @article = Article.find(params[:id])
end

def index
  @articles = Article.all.reverse
end

def edit
    @article = Article.find(params[:id])
end

def update
  @article = Article.find(params[:id])

  if @article.update(article_params)
    redirect_to @article
  else
    render 'edit'
  end
end

def destroy
  @article = Article.find(params[:id])
  @article.destroy

  redirect_to articles_path
end

private
  def article_params
    params.require(:article).permit(:title, :text, :date, :kredit, article_categories_attributes: [:id, :sport])
  end

end

文章模型

class Article < ActiveRecord::Base
    has_many :comments, dependent: :destroy
    has_many :article_categories, dependent: :destroy
    accepts_nested_attributes_for :article_categories, :allow_destroy => true
  validates :title, presence: true,
                    length: { minimum: 5 }


end

我们无法弄清楚为什么我们无法在Article.last上调用此方法

1 个答案:

答案 0 :(得分:1)

由于我的评论有帮助,我会将此作为答案添加,以便我们可以关闭此

如果您在对模型进行更改时打开控制台,则在您退出并重新进入控制台或键入reload!之前,这些更改尚未反映出来。这些中的任何一个都会导致控制台重新加载所有类。简而言之,您的课程保持在您第一次加载控制台时的状态,因此当您在控制台中同时开发和玩游戏时,请记住这一点。


关于您在评论中提出的问题:

当我们调用文章的实例 - @ article.article_categories时 - 我们得到<ArticleCategory::ActiveRecord_Associations_CollectionProxy:0x007fc46acc5db8>

这是正确的,你得到一个关联对象。大多数情况下你不必担心这个问题,因为调用一些数组方法(例如.each等)将为你提供具体的对象。

但是,集合代理对象允许您执行其他活动记录方法调用,以便根据需要进一步过滤article_categories列表。你可以做这样的事情,例如:

article.last.article_categories.where(sport: "curling")

article_categories列表将仅限于与.where子句过滤器匹配的列表。您可以通过查看生成的SQL查询在控制台或rails日志中对此进行验证。

希望有所帮助。