3. REST, Resources, and Rails - 3.12 The RESTful Rails Action Set

3.12 The RESTful Rails Action Set

3.12.1 Index

Typically, an index action provides a representation of a plural (or collection) resource. However, to be clear,not all resource collections are mapped to the index action. Your default index representations will usually be generic, although admittedly that has a lot to do with your application-specific needs. But in general, the index action shows the world the most neutral representation possible.

class AuctionsController < ApplicationController
  def index
    @auctions = Auction.all
  end
end

The associated view template will display information about each auction, with links to specific information about each one, and to profiles of the sellers.

You’ll certainly encounter situations where you want to display a representation of a collection in a restricted way. In our recurring example, users should be able to see a listing of all their bids, but maybe you don’t want users seeing other people’s bids.

There are a couple of ways to do this. One way is to test for the presence of a logged-in user and decide what to show based on that. But that’s not going to work here. For one thing, the logged-in user might want to see the more public view. For another, the more dependence on server-side state we can eliminate or consolidate, the better.
So let’s try looking at the two bid lists, not as public and private versions of the same resource, but as different index resources. The difference can be reflected in the routing like:

resources :auctions do 
  resources :bids do
    get :manage, :on => :collection 
  end
end

resources:bids

We can now organize the bids controller in such a way that access is nicely layered, using action callbacks
only where necessary and eliminating conditional branching in the actions themselves:

class BidsController < ApplicationController 
  before_action :check_authorization, only: :manage
  def index
    @bids = Bid.all
  end

  def manage
    @bids = auction.bids
  end

  protected

  def auction
    @auction ||= Auction.find(params[:auction_id])
  end

  def check_authorization 
    auction.authorized?(current_user)
  end 
end

There’s now a clear distinction between /bids and /auctions/1/bids/manage and the role that they play in your application.

On the named route side, we’ve now got bids_url and manage_auction_bids_url. We’ve thus preserved the public, stateless face of the /bids resource, and quarantined as much stateful behavior as possible into a discrete member resource, /auctions/1/bids/manage. Don’t fret if this mentality doesn’t come to you naturally. It’s part of the REST learning curve.

3.12.2 Show

The RESTful show action is the singular flavor of a resource. That generally translates to a representation ofinformation about one object, one member of a collection.

class AuctionController < ApplicationController
  def show
    @auction = Auction.find(params[:id])
  end
end

3.12.3 Destroy

Destroy actions are good candidates for administrative safeguarding, though of course it depends on whatyou’re destroying. You might want something like this to protect the destroy action.

class ProductsController < ApplicationController
  before_action :admin_required, only: :destroy
def destroy
  product.destroy
  redirect_to products_url, notice: "Product deleted!"
end

This approach might be reflected in a simple administrative interface like

%h1 Products 
- products.each do |product|
  %p= link_to product.name, product 
  - if current_user.admin?
    %p= link_to "delete", product, method: :delete

The Rails UJS (Unobtrusive JavaScript) API greatly simplifies the HTML emitted for a destroy action, using CSS selectors to bind JavaScript to (in this case) the “delete” link.

DELETE submissions are dangerous. Rails wants to make them as hard as possible to trigger accidentally—for instance, by a crawler or bot sending requests to your site. So when you specify the DELETE method, JavaScript that submits a form is bound to your “delete” link, along with a rel="nofollow" attribute on the link. Since bots don’t submit forms (and shouldn’t follow links marked “nofollow”), this gives a layer of protection to your code.

3.12.4 New and Create

As you’ve already seen, the new and create actions go together in RESTful Rails. A “new resource” is really just an entity waiting to be created. Accordingly, the new action customarily presents a form, and create creates a new record, based on the form input.

Let’s say you want a user to be able to create (that is, start) an auction. You’re going to need

  1. A new action, which will display a form
  2. A create action, which will create a new Auction object based on the form input, and proceed to a
    view (show action) of that auction.
protected

def auction
  @auction ||= current_user.auctions.build(params[:auction])
end
helper_method:auction

Once the information is filled out by a user, it’s time for the main event: the create action. Unlike new, this action has something to do.

def create
  if auction.save
    redirect_to auction_url(auction), notice: "Auction created!" 
  else
    render :new 
  end
end

3.12.5 Edit and Update

Like new and create, the edit and update actions go together: edit provides a form, and update processes the form input.

The form for editing a record appears similar to the form for creating one. (In fact, you can put much of it in a partial template and use it for both; that’s left as an exercise for the reader.)

The form_for method is smart enough to check whether the object you pass to it has been persisted or not. If it has, then it recognizes that you are doing an edit and specifies a PATCH method on the form.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市泄鹏,隨后出現(xiàn)的幾起案子郎任,更是在濱河造成了極大的恐慌,老刑警劉巖备籽,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件舶治,死亡現(xiàn)場(chǎng)離奇詭異分井,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)霉猛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門尺锚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人惜浅,你說(shuō)我怎么就攤上這事瘫辩。” “怎么了坛悉?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵伐厌,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我裸影,道長(zhǎng)挣轨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任空民,我火速辦了婚禮刃唐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘界轩。我一直安慰自己,他們只是感情好衔瓮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布浊猾。 她就那樣靜靜地躺著,像睡著了一般热鞍。 火紅的嫁衣襯著肌膚如雪葫慎。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天薇宠,我揣著相機(jī)與錄音偷办,去河邊找鬼。 笑死澄港,一個(gè)胖子當(dāng)著我的面吹牛椒涯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播回梧,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼废岂,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了狱意?” 一聲冷哼從身側(cè)響起湖苞,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎详囤,沒想到半個(gè)月后财骨,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年隆箩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了该贾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡摘仅,死狀恐怖靶庙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情娃属,我是刑警寧澤六荒,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站矾端,受9級(jí)特大地震影響掏击,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜秩铆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一砚亭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧殴玛,春花似錦捅膘、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至凡壤,卻和暖如春署尤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亚侠。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工曹体, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人硝烂。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓箕别,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親钢坦。 傳聞我的和親對(duì)象是個(gè)殘疾皇子究孕,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • PLEASE READ THE FOLLOWING APPLE DEVELOPER PROGRAM LICENSE...
    念念不忘的閱讀 13,433評(píng)論 5 6
  • **2014真題Directions:Read the following text. Choose the be...
    又是夜半驚坐起閱讀 9,399評(píng)論 0 23
  • 關(guān)于運(yùn)動(dòng)健康減肥禾酱,總想找一種效果最好的微酬, 但也要是自己喜歡绘趋,這樣更有利于減肥瘦身 其實(shí)2個(gè)方面去分就好 第一種健康...
    視俗遇閱讀 356評(píng)論 0 0
  • 燈草生活在一個(gè)很美麗的森林里,周圍有自由的風(fēng)颗管,清新的空氣陷遮,生機(jī)盎然~許許多多的小動(dòng)物和平而又開心的生活在這里,因?yàn)?..
    帆明閱讀 487評(píng)論 2 0
  • 進(jìn)京回來(lái)垦江,打算記錄一下帽馋,便細(xì)細(xì)回憶一下自己去過(guò)幾次北京: 剛來(lái)新東方頭一年十一月去北京參加少兒市場(chǎng)會(huì)。 到中學(xué)后比吭,...
    陳力石閱讀 203評(píng)論 0 0