Rails 4:分配记录 "has many" 属性而不保存数据库

Rails 4: Assigning a records "has many" attribute without database saving

我有几个模型如下所示,我正在使用 Thing 中的搜索 class 方法来过滤记录

class Category << ActiveRecord::Base
  has_many :thing
end

class Thing << ActiveRecord::Base
  belongs_to :category

  :scope approved -> { where("approved = true") }

  def self.search(query)
    search_condition = "%" + query + "%"
    approved.where('name LIKE ?', search_condition)
  end
end

它在我的 Things 控制器中运行良好。索引路由如下所示:

def index
   if params[:search].present?
     @things = Thing.search(params[:seach])
   else
     @thing = Thing.all
   end
end

在类别显示路线上,我显示了该类别的事物。我还有在类别中搜索的搜索表单。

def show
  @category = Categories.find(params[:id])

  if params[:search].present?
     @category.things = @category.things.search()
  end
end

所以问题是,当我在 categories#show 路由中使用搜索 class 方法时,所有过滤的东西的 category_id 属性都设置为 nil .为什么要把它保存到数据库?我以为我必须为此调用 @category.saveupdate_attribute。我对 rails 还是个新手,所以我确定它很容易被我忽略或误读。

我目前的解决方案是将 if 语句移动到视图中。但是现在我正在尝试向它添加带有 kaminiri 的页面并且它变得越来越丑陋。

<% if params[:search].present? %>
  <% @category.things.search(params[:search]) do |thing| %>
   ... Show the filtered things!
  <% end %>
<% else %>
  <% @category.things do |thing| %>
  ... Show all the things!
  <% end %>
<% end %>

我想到的另一个解决方案是使用 @things = @categories.things.search(params[:search]) 但这意味着我将重复的东西传递给视图。

就像严说的,"In your example you are actually assigning all the things found using @category.things.search() to the Category which has previously been queried using Categories.find(params[:id])"。验证将解决这个问题。

记录被保存为 nil,因为您没有对您的模型进行验证。阅读活动记录 validations。 这是他们提供的示例。您还想验证存在性,因为创建的记录没有值。

class Person < ActiveRecord::Base
  validates :name, presence: true
end

Person.create(name: "John Doe").valid? # => true
Person.create(name: nil).valid? # => false

看看Rails guidehas_many 关联在 collection=(objects) 也属于的模型上创建了许多方法。根据指南:

The collection= method makes the collection contain only the supplied objects, by adding and deleting as appropriate.

在您的示例中,您实际上是将使用 @category.things.search() 找到的所有 thing 分配给之前使用 Categories.find(params[:id]).[=18= 查询过的 Category ]