i have a view called week.haml
and a controller action called def week
in which I get all my todos for this week. I want to render a partial called _events.haml
inside week.haml
which displays all events that week.
I did it like this:
inside week.haml
:
= render partial: 'events`
inside _events.haml
%p= 'Events this week:'
@events.each do |event|
# stuff to show events
end
inside the todo controller:
def events
@events = Event.where(some query)
end
But i always get the error message @events not defined
. How can i load events into the event partial? and i don't want to do it inside def week
if possible...
I also created a route:
resources :todo do
get 'events', action: :events, as: :events
end
The week.haml
file works fine, just the partial doesn't work.
CodePudding user response:
It is bad practice to use instance variables in partials, pass locals instead. Instance variables are for views
In your week
view
= render partial: 'events`, events: week.events
And in partial _events
events.each do |event|
# stuff to show events
end
CodePudding user response:
If you're in the controller action week
, you'll need to get the events there or share @events
between the different controller actions. If you're in the same scope (same controller in this case), you could create a private method for getting data that's similar between different views.
class TodoController < ApplicationController
before_action :get_events, only: [:week, :events]
def week
# Stuff for the week view
end
def events
# Stuff for the events view
end
private
def get_events
@events = Event.where(...)
end
end
In this example, the @events
variable is available for both actions week
and events
. The before_action
at the top runs get_events
to load the @events
variable before executing any other code in the controller action. Since it's an instance variable, it can be shared between different methods in the same class. Calling get_events
at the top of both week
and events
would achieve the same result, but a before_action
is usually cleaner IMO.
And just to be clear, all of this is assuming that you have separate views events.haml
and week.haml
. If not, creating a route and a controller method with the name of the partial does nothing. Just load the events in the week
controller action and you're good to go! You could essentially think of a controller method as corresponding to a single view (of the same name usually), and a partial is just an extension of that view (and any other views that use the same partial). You load any data you might need for the view or any of its partials in the controller action, and then share whatever's needed with the partial. Instance variables (starting with "@") are shared automatically, but anything else you would need to pass to the partial explicitly.
Partials are meant for things you need to render multiple times (and/or in multiple places). The Rails docs have a pretty thorough section about them. If you're only rendering events for a single week in week.haml
, you probably don't even need the partial, unless you want to use it in other views.