2017-08-12 377 views
1

我對rails很陌生,並且遇到了一些麻煩。我有一個名爲BusinessDates的模型,它包含兩個表格calendar_date和季節性(您可以忽略季節性)。我想要實現的是能夠像文件夾一樣輕鬆地穿過它們。Rails /(year)/(month)/(day)separate pages

這花了我幾天的谷歌富,但我能夠索引顯示每個獨特的一年的列表作爲與friendly_ids的鏈接。從這裏我想點擊它並將其鏈接到一個新的視圖,該視圖顯示該特定年份中每個唯一月份的列表,以便與friendly_ids鏈接。然後(如您猜測的那樣)在另一個新視圖上顯示所選年份中所選月份中所有日期的列表。我想要的網址是business_dates/2016/5/21或換句話說business_dates /(年)/(月)/(日)。

我的問題:我不知道從哪裏去。我似乎甚至無法找到任何有關製作第二級深度非靜態網址的信息,而無需每年製作獨立模型(想避免這種情況),或者看起來像是一個rube goldberg機器,沒有每個頁面的意見(你只需要輸入完整的日期到網址)。

請幫助一個感覺很失落的初學者!

控制器:

def index 
    @years = BusinessDate.pluck(:calendar_date).map{|x| x.year}.uniq 
end 

index.erb.html

<table> 
    <tr> 
     <th>Year</th> 
    </tr> 
    <% @years.sort.each do |year| %> 
    <tr> 
     <td><%= link_to year, business_date_path(year) %></td> 
    </tr> 
<% end %> 
</table> 

回答

0

我終於弄明白了,並得到它的工作,所以我會分享我的答案。大道具來幫忙!這有點亂,可能不是我應該這樣做的正確方式,但我的第一個目標是讓它工作並學習它如何它沿途。現在我正在整理並學習最佳實踐。

路線

Rails.application.routes.draw do 
resources :business_dates, except: :show 

get '/business_dates/:year/:month/:day', to: 'business_dates#edit_date', as: 'edit_date' 
get '/business_dates/:year/:month', to: 'business_dates#by_days', as: 'by_days' 
get '/business_dates/:year', to: 'business_dates#by_months', as: 'by_months' 
delete '/business_dates/:year/:month/:day', to: 'business_dates#delete_date', as: 'delete_date' 

控制器

class BusinessDatesController < ApplicationController 

def index 
    @business_dates = BusinessDate.all 
    @years = BusinessDate.pluck(:calendar_date).map{|x| x.year}.uniq 
end 

def new 
    @date = BusinessDate.new 
end 

def by_months 
    @months = BusinessDate.where("strftime('%Y', calendar_date) = ?", params[:year]) 
    @months = @months.pluck(:calendar_date).map{|x| x.strftime('%m')}.uniq 
end 

def by_days 
    @days = BusinessDate.where("cast(strftime('%Y', calendar_date) as int) = ? AND cast(strftime('%m', calendar_date) as int) = ?", params[:year], params[:month]) 
end 

def edit_date 
    set_business_date 
end 

def create 
    @date = BusinessDate.new(date_params) 
    if @date.valid? 
     @date.save 
     redirect_to by_days_path(@date.calendar_date.year, "%02d" % @date.calendar_date.month) 
    else 
     flash.now[:alert] = "New business date could not be saved" 
     render action: "new" 
    end 
end 

def update 
    #set_business_date 
    @date = BusinessDate.find(params[:id]) 
    @date.update(date_params) 
    redirect_to by_days_path(@date.calendar_date.year, "%02d" % @date.calendar_date.month) 
end 

def delete_date 
    set_business_date 
    @date.destroy 
    redirect_to by_days_path(params[:year], params[:month]) 
end 

private 

def set_business_date 
    @date = BusinessDate.where("cast(strftime('%Y', calendar_date) as int) = ? AND cast(strftime('%m', calendar_date) as int) = ? AND cast(strftime('%d', calendar_date) as int) = ?", params[:year], params[:month], params[:day]).first 
end 

def date_params 
    params.require(:business_date).permit(:calendar_date, :seasonality) 
end 
end 

index.html.erb

<h1>Business Dates by Year</h1> 


<table> 
<tr> 
    <th>Calendar Date</th> 
</tr> 
<% @years.sort.each do |year| %> 
<tr> 
    <td><%= link_to year, business_date_path(year) %></td> 
</tr> 
<% end %> 
</table> 

<br> 

<%= link_to 'Create New Business Date', new_business_date_path %> 

by_months.html.erb

<h1><%= params[:year] %></h1> 


<table> 
<tr> 
    <th>Months</th> 
</tr> 
<% @months.sort.each do |month| %> 
<tr> 
    <td><%= link_to Date::MONTHNAMES[month.to_i], by_days_path(params[:year], month) %></td> 
</tr> 
<% end %> 
</table> 

<br> 

<%= link_to 'Create New Business Date', new_business_date_path %> 
<br> 
<%= link_to 'Back to Years', business_dates_path %> 

by_days.html.erb

<h1><%= Date::MONTHNAMES[params[:month].to_i] %>, <%= params[:year] %> <%= params[:id] %></h1> 

<table> 
<tr> 
    <th>Date</th> 
    <th>Seasonality</th> 
    <th>ID</th> 
</tr> 
<% @days.sort.each do |day| %> 
<tr> 
    <td><%= day.calendar_date.day %></td> 
    <td><%= day.seasonality %></td> 
    <% %> 
    <td><%= day.id %></td> 
    <td><%= link_to 'Edit', edit_date_path(day.calendar_date.year, "%02d" % day.calendar_date.month, day.calendar_date.day) %></td> 
    <td><%= link_to 'Delete', delete_date_path(day.calendar_date.year, "%02d" % day.calendar_date.month, day.calendar_date.day), method: :delete, data: { confirm: 'Are you sure?' } %></td> 
</tr> 
<% end %> 
</table> 

<br> 

<%= link_to 'Create New Business Date', new_business_date_path %> 
<br> 
<%= link_to 'Back to Months', by_months_path %> 
<br> 
<%= link_to 'Back to Years', business_dates_path %> 

這是所有工作正常,但我希望我能想出我的:ID發佈。不知道如何使用:year /:month /:day url約定通過:id查找記錄。這個應用程序不是問題,考慮到應該永遠不會超過同一天的一個,但它會有幫助,我相信它會減少必須通過params [:year]搜索記錄, [:月]和[:日]。這件事是一個神聖的恐怖,但我肯定了解了數組,哈希,符號,屬性,模型,方法和實例變量之間的差異!

0

您可以創建自定義路線。由於我不知道你正在使用的確切的控制器動作等,我會給你一個普遍的答案。你可以像路(將達到BusinessDatesController的:show_full_date動作):

get 'business_dates/:year/:month/:day', to: 'business_dates#show_full_date' 

您可以鏈接到它像(運行rake路線檢查正確的路徑):

<%= link_to your_date, full_date_business_dates_path('1985','5','21') %> 

瞭解這裏最重要的是,路徑幫助程序最終只是一個可以接受參數的方法。它能夠接受的是在routes.rb中定義的。因此,在我們的情況下,它將會:年,月和日參數。

一旦你點擊這個鏈接並點擊:show_full_date動作,你可以使用params [:year],params [:month],params [:day]提取年份,月份和日期,並隨時隨地處理它們做。您可以類似地爲年份或月份定義路線。希望這可以幫助。

編輯:你也可以給路由定義中的as:選項指定一個特定的路徑名​​稱,如as: 'my_funky_name'

此外,我應該補充說,你應該保持這樣的自定義路由到最低限度。當有必要的時候,然後去做。否則堅持默認值。

+0

我對這是如何工作有點困惑。 因此,如果每年都有一個記錄(2005年,2006年,2007年等),並且我點擊2007年,它應該鏈接到business_dates /:year。但是由於我沒有縮小完整日期,所以只有在calendar_date列中匹配2007年的所有記錄,這對我來說無法實現。我需要從一開始就有預定的日期。對? 我重申,我是新的。 – backsliders

+0

你可以有不同的途徑: 'business_dates /:年/月/:day' 'business_dates /:年/:month' 'business_dates /:year' 年頁列出了所有個月鏈接。月份頁面將所有日期列爲鏈接,因此您可以查看完整日期頁面。 我剛剛給你一個方法來創建自定義路線 - 你可以使用它們,但你想:) – arunt

+0

我欣賞不斷的幫助。我仍然對如何在控制器中設置它感到困惑。我一直在爲此工作近一個星期,而且我一直在打擊死衚衕。 – backsliders

相關問題