Рельсы / (год) / (месяц) / (день) отдельные страницы

Я новичок в рельсах, и у меня возникли проблемы. У меня есть модель BusinessDates, которая состоит из двух таблиц: calendar_date и Seasonality (сезонность можно игнорировать). Я пытаюсь легко перемещаться по ним, как по папкам.

На использование google-foo у меня ушло несколько дней, но я смог отобразить в индексе список каждого уникального года в порядке ссылок на friendly_ids. Отсюда я хочу щелкнуть по нему и получить ссылку на новое представление, которое отображает список каждого уникального месяца в этом конкретном году в порядке ссылок с friendly_ids. Затем (как вы могли догадаться) отобразить в другом новом представлении список всех дней в выбранном месяце в выбранном году. Я хочу, чтобы URL-адрес был business_dates / 2016/5/21 или, другими словами, business_dates / (год) / (месяц) / (день).

Моя проблема: я не знаю, что делать дальше. Кажется, я даже не могу найти никакой информации о создании глубокого нестатического URL-адреса второго уровня без создания отдельных моделей для каждого месяца и дня (хочу избежать этого) или того, что выглядит как машина Руба Голдберга, чтобы добраться туда, но без просмотров для каждой страницы (вам нужно просто ввести полную дату в URL-адрес).

Пожалуйста, помогите новичку, который чувствует себя очень потерянным!

Контроллер:

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>

person Community    schedule 12.08.2017    source источник


Ответы (2)


Вы можете создать собственный маршрут. Поскольку я не знаю, какие именно действия контроллера и т. Д. Вы используете, я дам вам общий ответ. Вы можете выполнить маршрутизацию следующим образом (вызовет действие :show_full_date BusinessDatesController):

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

Вы можете связать его как (запустите rake routes, чтобы проверить правильный путь):

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

Здесь важно понимать, что помощник по пути - это, в конце концов, просто метод, который может принимать аргументы. То, что он может принимать, определяется в файле routes.rb. Итак, в нашем случае это будут параметры: year,: month и: day.

После того, как вы нажмете эту ссылку и нажмете действие :show_full_date, вы можете извлечь год, месяц, дату, используя params [: year], params [: month], params [: day], и делать с ними все, что вам нужно. Аналогичным образом вы можете определить маршруты только на год или месяц. Надеюсь это поможет.

РЕДАКТИРОВАТЬ: Вы также можете указать параметр as: в определении маршрута, чтобы указать конкретное имя пути, например as: 'my_funky_name'.

Кроме того, я должен добавить, что вы должны свести количество таких настраиваемых маршрутов к минимуму. Когда нужно, то и делай. В противном случае придерживайтесь значений по умолчанию.

person arunt    schedule 12.08.2017
comment
Я немного запутался в том, как это работает. Итак, если у меня он отображается каждый год, в котором есть запись (2005, 2006, 2007 и т. Д.), И я нажимаю на 2007, он должен ссылаться на business_dates /: year. Но поскольку я не сузил полную дату, а только все записи, соответствующие 2007 году в столбце calendar_date, это не помогло бы мне добиться этого. Мне нужно было бы иметь предполагаемую дату с самого начала. Правильно? Повторяю, я новенький. - person ; 12.08.2017
comment
У вас могут быть отдельные маршруты: business_dates/:year/:month/:day business_dates/:year/:month business_dates/:year На странице года перечислены все месяцы в виде ссылок. На странице месяца все даты перечислены в виде ссылок, и вы попадете на страницу с полной датой. Я только что дал вам способ создания собственных маршрутов - вы можете использовать их как хотите :) - person arunt; 13.08.2017
comment
Ценю постоянную помощь. Я все еще не понимаю, как это настроить в контроллере. Я работаю только над этим уже почти неделю, и все время захожу в тупик. - person ; 15.08.2017
comment
Чтобы быть более конкретным, в контроллере у меня есть: `def show_months @months = BusinessDate.where (strftime ('% Y',: calendar_date) =?,: Year) end` Но все, что он показывает, это #‹ BusinessDate :: ActiveRecord_Relation : 0x0000000c7a30f8 › - person ; 15.08.2017
comment
Я также попробовал @months = BusinessDate.all.select {| date | date.calendar_date.year == params [: year]} Я подтвердил, что params [: year] возвращает год, который я выбрал, но этот запрос activerecord возвращает пустой массив. - person ; 15.08.2017
comment
Во-первых, не волнуйтесь, потому что даже я столкнулся с проблемами, когда только начал изучать Rails. Через год вы сочтете этот вопрос тривиальным! Вы пробуете эти вещи в консоли Rails? Вот где я провожу всевозможные эксперименты. Вы :calendar_date столбец - это объект даты или дата-время? Можете ли вы опубликовать результат вызова inspect для объекта BusinessDate? puts BusinessDate.first.inspect например. Следующая ссылка также может быть вам полезна: Вопрос, связанный с Stackoverflow - person arunt; 15.08.2017

Я наконец понял это и получил работу, поэтому я поделюсь своим ответом. большие надежды наручать за помощь! Это немного запутано и, вероятно, не так, как мне следовало бы это делать, но моей первой целью было заставить его работать и попутно изучить как. Теперь я хочу привести себя в порядок и изучить передовой опыт.

Маршруты

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. Не уверен, как найти запись по: id при использовании соглашения об URL-адресах: year /: month /: day. Это не проблема для этого приложения, учитывая, что никогда не должно быть более одной даты с одинаковой датой, но это было бы полезно, и я уверен, что это уменьшило бы необходимость поиска записи по параметрам [: год], [: месяц] и [: день]. Это было настоящим ужасом, но я определенно много узнал о различиях между массивами, хешами, символами, атрибутами, моделями, методами и переменными экземпляра!

person Community    schedule 16.08.2017