I'm trying to make it so that I can have a urls like this:
/events
/events/sunday # => The day is optional
However, it doesn't seem to be working even though I know it is getting called. It is at the bottom of my routes file.
match '/:post(/:day_filter)' => 'posts#index', :as => post_day_filter, :constraints => DayFilter.new
class DayFilter
def initialize
#days = %w[all today tomorrow sunday monday tuesday wednesday thursday friday saturday]
end
def matches?(request)
return #days.include?(request.params[:day_filter]) if request.params[:day_filter]
true
end
end
Here is my rake routes output:
post_day_filter /:post(/:day_filter)(.:format) {:controller=>"posts", :action=>"index"}
I'm not sure what the problem is, specifically, but the following is a much more performance-friendly way of doing the same thing:
class ValidDayOfWeek
VALID_DAYS = %w[all today tomorrow sunday monday tuesday wednesday thursday friday saturday]
def self.matches?(request)
VALID_DAYS.include? request.params[:day_of_week]
end
end
get ':/post_type(/:day_of_week)' => 'posts#index', :constraints => ValidDayOfWeek
The biggest difference is that this avoids initializing a new ValidDayOfWeek object on every request. The Rails guide gives an example where you might want a fresh object each time (real-time blacklist updating), but it's misleading for cases like yours.
Also, you were getting a bit verbose in your matches? method — no need for explicit returns or a conditional, as includes? will return either true or false as is.
Related
I'm creating a Calendar to view of a week without the Calendar gem. (It will get pretty specific past the use of that gem).
When I render a view to see a page (index) it will display the dates and days for that particular week. How can I make a button that is clickable that will change those dates to the previous week or the next week?
I'm confused on how to do it, and am looking for coding suggestions of course. How I have attempted this so far is I have created two helper functions to add the days to my current variables. Then I want to display the same page after the helper function updates to the next week or previous week.
Here is how I am calling my helper function
<%= link_to '<', week_ahead, class: 'month-arrow' %>
def week_ahead
#viewDate = #viewDate + 7.days
#weekStart = #viewDate.beginning_of_week(start_day = :monday)
end
helper_method :week_ahead
def week_back
#viewDate = #viewDate - 7.days
#weekStart = #viewDate.beginning_of_week(start_day = :monday)
end
helper_method :week_back
Here is what I am using in my controller
def index
#user = User.find(session[:user_id])
#viewDate = Date.today
#weekStart = #viewDate.beginning_of_week(start_day = :monday)
end
If I put a redirect_to user_path command in the helper function it gives a redirect loop. I still want my view to update to the next week when they click on the "next arrow".
Use simple calender gem. It is really helperful.https://github.com/excid3/simple_calendar
I am trying to set up some semistatic page in a rails 3 app,
I have created a Pages controller with some non restful actions
class PagesController < ApplicationController
def home
end
def about
end
def contact
end
def monday
end
def saturday
end
def sunday
end
end
it's showing the pages well at pages/monday etc... or /monday etc... if i set up the routes as is rails 3 removing controller name form url
But I was just wondering if it is possible to redirect a missing url to /. As per exampel i have /monday set up, but if one plays with the url and input /tuesday it won't hit a page. can i redirect this kind of actions?
==EDIT==
I've change my code to this:
resources :pages, :path => '/' do
collection do
# # match 'tuesday' => redirect('/')
# # match 'wednesday' => redirect('/')
# # match 'friday' => redirect('/')
%w{home monday thursday saturday sunday about contact resources}.each do |url|
get url
end
end
end
match 'pages/*page' => :root
the url rewriting works fine looping through the array.
I tried the put the wild cardline at the bottom of my root files and at the bottom of the resources :page block. But I get a "controller action show could not be found" message.
match 'pages/*page' => :root
IS that the correct place to put it to restrain missing url like /tuesday to generate an error page?
is it also possible to limit this redirection only to a few actions and not to all missing pages? ex only to tuesday, wednesday, friday...
You can use wildcard routes to do this. At the end of your routes.rb just add the line:
match '*page' => :root
and the missing pages will redirect to root with params[:page] set to the url requested.
If you want to only redirect missing pages in the Pages controller, do this instead
match 'pages/*page' => :root
You can read more about routing here. Wildcard routes are explained near the end of the article.
Hope this helped!
got it working
I changed the wildcard line to
match '*page' => redirect('/')
instead of => :root, and left it within the resources :pages block.
I have a Rails3 app that has Workflows, and they have many WorkAssignments. WorkAssignments have a field, work_sent_date, the date work was sent to the person. On the Workflow edit screen I display a work sent date field, but Workflow does not have an attribute work_sent_date. If any work assignments have a date, I display the most recent one and it can't be edited. If all are blank, I display a text box that is editable and in WorkflowController#update, if that date is filled it, the work assignments' work_sent_date field get that date.
It works when I test it manually. I suppose I could just create an attribute for it, but I'm trying to be slick and not have redundant data.
I'm trying to write a test for this. First I assert that the WorkAssignment#work_sent_date is blank for all work assignments. Then I try a "post :update" and I can't figure out how to pass in the work_sent_date value, which is a form field but not an attribute. What I want to do is something like.
test "setting work_sent_date in wf sets it in wa" do
#workflow.work_assignments.each do |wa|
assert wa.work_sent_date.blank?
end
get :edit, :id => #workflow.id
assert_response :success
post :update, :workflow => #workflow.attributes, :parameters => {'work_sent_date' => Date.today.to_s}
#workflow.work_assignments.each do |wa|
assert_equal(wa.work_sent_date, Date.today)
end
end
But that parameters field doesn't work. There's no error, but I keep getting failures because wa.work_sent_date is still nil, so it's not getting passed in correctly. How do I pass today's date in as an extra parameter?
(Or maybe there's a better way to do the whole thing, which I would gladly consider.)
I know this is complicated. I hope I explained it well. Any suggestions would be appreciated. I've googled to death and can't find anything.
Found my problem. Syntax way wrong. Here's what it should be. This works.
put :update, :id => #workflow.id, :workflow => #workflow.attributes, :work_sent_date => Date.today.to_s
You can also refactor out the create and edit as follows:
protected
def edit_workflow(workflow, options = {})
post :update, :id => workflow.id, :workflow => workflow.attributes.merge(options)
end
def create_workflow(options = {})
post :create, :workflow => {}.merge(options)
end
end
I have two models, Trip and Day, with a one-to-many relationship. For the time being I do not want to make Day an embedded document.
class Day
include MongoMapper::Document
...
key :trip_id, ObjectId
belongs_to :trip
end
class Trip
include MongoMapper::Document
...
key :day_ids, Array
many :days, :in => :day_ids
end
I would like to be able to create routes that look like this:
/trips/:trip_id/days/:index_of_day
Where :index_of_day would be used to find the nth day in a trip #trip.days[:index_of_day], so a person could easily navigate to the first, second, etc. day of a trip.
Currently my route.rb file looks like this:
resources :trips do
resources :days
end
Which generates the default routes /trips/:trip_id/days/:day_id.
One partway solution I had was to put in my route.rb file
match 'trips/:trip_id/day/:id' => 'days#show'
And then in my Days Controller
def show
#day = Trip.find(params[:trip_id]).days(params[:id].to_i)
...
end
This sort of worked except all of the helpers like trip_day_path automatically redirect using the day id, not the day index.
If you want your helpers to use the index instead of the day id, you can define to_param in your Day model. Rails calls to_param on your object to find out what to put in the URL.
class Day
# ...
# many :in is for many-to-many, but you are using it for one-to-many
# either way, many :in doesn't have an inverse yet
def trip
Trip.first('day_ids' => self.id)
end
def to_param
trip.days.find_index(self)
end
end
You'll notice that's kind of hackish, which is a code smell.
is it possible to advance a variable something like #current_month = Date.today.month+1 then forward it back to the index page, if so how
#current_month = Date.today + 1.month
Not sure quite what you mean by 'forward it back to the index page', but if you then
render :action => 'index'
the #current_month instance variable will be available to the index view of that controller. You could print out the month only by using strftime, eg <%= #current_month.strftime("%B") %>
Check out .strftime at http://www.ruby-doc.org/core/classes/Time.html#M000392
For calendar operations, one probably wants to start at the beginning of the month.
#current_month = 1.month.from_now.beginning_of_month
This will return a ActiveSupport::TimeWithZone object which is similar to Ruby's DateTime.
OR
#current_month = Date.today.at_beginning_of_month.next_month
which will return a Ruby Date object.