[英]How to choose a single model and persist that choice?

I have a simple model called Party with a corresponding table called parties. There's also a controller with all the usual CRUD actions and so on. This model is used in a website and only one admin user is allowed to edit the parties - everyone else is allowed to call GET actions (index, show). Nothing special so far.

我有一個簡單的模型,叫做Party,對應的表格叫做parties。還有一個具有所有常規CRUD操作的控制器等等。該模型在網站中使用,只有一個管理員用戶可以編輯各方——其他人可以調用GET操作(index, show)。到目前為止沒有什么特別的。

Now I need to do the following: The admin would like to choose a single Party at a time for special presentation (the selected Party is showing up on the start page of the application). The most important thing is, that there's only ONE party at time selected.


How would you solve this problem? Boolean Flag in Party model? Save the selection (id of the party) somewhere outside the database? Implement a new model with a has_one relation to Party (seems like overkill to me)?


I hope my explanation is good enough to understand the issue.


5 个解决方案



A simple "front_page" attribute would suffice or another model like you mentioned, using the has_one relationship would be fine as well.


Using another model would allow you to maintain some more information, like how long should it remain on the front page (expiration date?) or how many times it was featured (assuming a party can be featured twice). It really depends on other requirements for your system.


You also might be able to get away with a simple implementation of the Singleton pattern as well. There's a quick description on the Rails Wiki of making an ActiveRecord object a Singleton (see below): http://wiki.rubyonrails.org/rails/pages/TipsAndTricks


Making a singleton ActiveRecord object


If you have a table with just one entry, useful for keeping track of a number sequence for databases without sequences, you can use the singleton module included with ruby like so:


require 'singleton'

class Master < ActiveRecord::Base
  include Singleton
  def initialize(args=nil) super(args) if record = Master.find(:first)    
    self.attributes = record.attributes end end def next_tracking_number increment!
    (:current_tracking_number) current_tracking_number end def 
    self.next_tracking_number instance.next_tracking_number 



This is a very poor code example (was copied and pasted from the Rails Wiki, which had no formatting). I would highly recommend the [Ruby Design Patterns] book which tackles many of the GoF design patterns in greater detail (while making them applicable to Ruby applications). But Google should return you some good resources for using the Singleton pattern in Ruby.2

這是一個非常糟糕的代碼示例(從Rails Wiki中復制和粘貼,沒有格式)。我強烈推薦《Ruby設計模式》這本書,它更詳細地處理了許多GoF設計模式(同時使它們適用於Ruby應用程序)。但是谷歌應該會為使用Ruby.2中的單例模式返回一些好的資源



I would go for the boolean flag and create nested singleton resource (promoted), which I would implement in PartiesController itself (set_promoted_party and get_promoted_party actions). For these I would create two new routes:


PUT /parties/promoted/:party_id # to set the promoted party
GET /parties/promoted/:party_id # to get the promoted_party



I would add a second model that had a has_one relationship in order to keep the app RESTful and simple. Also, this way, you can keep a history of special Parties, and track other meaningful information related to the special parties.




Personally I'm very strong on data integrity being enforced by my database so would probably add that extra table and enforce it as a foreign key constraint there. It can seem like overkill, but is the only* solution that prevents data integrity issues.


Could you maybe add it as a field to the admin table/model - which would be an enforced foreign key to the party table?


*Another solution would be a database trigger that checks no other rows are the selected party but I tend to shy away from such solutions.




Keep it simple. Put a promoted_party.yml file in your config directory that the controllers write to and read from. The contents can be as simple as this:


party_id: 123

Done. If you need more integrity or fancier relationships later, implement that later, not now.


For deployments, just make sure the file is symlinked to a shared directory to survive application upgrades.




粤ICP备14056181号  © 2014-2021 ITdaan.com