【问题标题】:Understanding associations in rails 3了解 Rails 3 中的关联
【发布时间】:2013-02-01 19:42:23
【问题描述】:

看来我需要重温一下我在 Rails 中的联想。目前我正在尝试显示所有以部门名称为员工的帖子。

目前有两种模式,职位和部门

class Post < ActiveRecord::Base
  belongs_to :department
  attr_accessible :title, :comments, :department_id
end

class Department < ActiveRecord::Base
  has_many :posts
  attr_accessible :name, :post_id
  #Scopes
  scope :staff_posts, where(:name => "Staff") 
end

所以我想显示部门名称为员工的所有帖子

为此,我已将其放入我的控制器中

class PublicPagesController < ApplicationController

  def staffnews
    @staffpost = Department.staff_posts
  end

end

在我看来,我正在尝试像这样显示所有这些帖子

<% @staffpost.each do |t| %>
  <h2><%= t.title %>
  <h2><%= t.comments %></h2>
<% end %>

当我得到未定义的方法 nil 时,显然某处出错了,即使我有 3 个名为“员工”的帖子

有人可以解释一下我在哪里误解了协会,因为我很想把这个做对

编辑

路线

scope :controller => :public_pages do 
get "our_news"

match "our_news/staffnews" => "public_pages#staffnews"

【问题讨论】:

  • “看来我需要重新认识我的联想”——我为此推荐一本书。结构化知识比 SO 帖子更有用。
  • 在控制器中,它返回带有名称员工的部门。你在部门对象上使用 title 和 cmets 这就是为什么没有方法错误发生
  • @SergioTulentsev 除了常规 Rails 文档之外的任何建议,即您是否遇到过简化解释的博客或帖子
  • 我不确定,我现在无法测试它,因为我远离我的笔记本电脑。但据我所知,您已经在部门模型中声明了范围,Department.staff_posts 将返回名称为“员工”的部门。我不确定,但@staffposts = Department.staff_posts.first.posts 应该获取帖子。如果这不起作用,那么您可以使用@staffposts = Department.find_by_name('staff').posts

标签: ruby-on-rails ruby ruby-on-rails-3 associations models


【解决方案1】:

在控制器中,它返回名称为员工的部门。而且您在部门对象上使用了 title 和 cmets,这就是它给出 nil 方法错误的原因。

这样使用:

 def staffnews
   @dept_staff = Department.staff_posts
 end

 <% @dept_staff.each do |ds| %>
   <% ds.posts.each do |p| %>
     <h2><%= p.title %></h2>
     <h2><%= p.comments %></h2>
   <% end %>
 <% end %>

在后期模型中创建named_scope

class Post < ActiveRecord::Base
  belongs_to :department
  attr_accessible :title, :comments, :department_id
  scope :staff_posts, :include => :department, :conditions => {"departments.name" => "Staff"}
end


class Department < ActiveRecord::Base
  has_many :posts
  attr_accessible :name, :post_id
end

控制器:

def staffnews
  @staffpost = Post.staff_posts
end

视图:#没有变化

<% @staffpost.each do |t| %>
  <h2><%= t.title %></h2>
  <h2><%= t.comments %></h2>
<% end %>

【讨论】:

    【解决方案2】:

    您的staff_posts 范围仅选择名称为“员工”的部门。假设您将有一个且只有一个名为 staff 的部门,您有几种方法可以处理此问题。

    这将找到所有名称为员工的部门,并急切地加载与之相关的帖子:

    @department = Department.where(name: "Staff").include(:posts).first
    

    但是,由于您尝试对 Post 进行范围划分,因此它属于 Post。下面是一个使用方法作为作用域的例子:

    class Post < ActiveRecord::Base
      belongs_to :department
      attr_accessible :title, :comments, :department_id
    
      def self.staff
        where(department_id: staff_department_id)
      end
    
      def staff_department_id
        Department.find_by_name!("Staff").id
      end
    
    end
    

    这样,您可以使用@staff_posts = Post.staff 并迭代该集合(注意:我不建议永久使用这种方式获取staff_department_id。可以在应用启动时将其设置为常量,或其他一些强大的解决方案)。

    【讨论】:

      【解决方案3】:

      您可以通过以下更改找到所有具有部门名称员工的帖子:

      类 PublicPagesController

      def staffnews
          #get all the department which have name is staff
          departments = Department.where("name=?","staff")
      
          #get all the ids
          department_ids = departments.map(&:id)
      
          #retrieve post that department name is staff 
          @staffpost = Post.find_by_department_id(department_ids)
      end
      

      结束

      【讨论】:

      • 根据变量的基数命名变量被认为是一种很好的做法。您的第一行最好写成departments = Department.where("name=?", "staff") 并相应地更改下一行。只是一条不相关的评论。
      • 谢谢,你提到的变量名我已经改了。
      猜你喜欢
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多