I've got a module that lists events (event_box) and I want to define it as part of my application.html.erb:
<div id="left_sidebar">
<%= render 'shared/user_box' %>
<%= render 'shared/event_box' %>
<%= render 'shared/server_info_box' %>
</div>
However, the event_box uses #events, which so far needs to be passed to it:
def home
#events = Event.all
end
If it's going to be in the application layout, how do I pass #events to it without defining #events in every view in my application?
Define a method in ApplicationController which fetches all the events.
Use this method as a before_filter in ApplicationController. Filters called in ApplicationController will apply to all the controllers inheriting from it.
application_controller.rb:
before_filter :fetch_events
def fetch_events
#events = Event.all
# #events = Event.where({}) can be used to lazy load the events
end
Since this is going to be executed before every action, consider using Fragment caching for that particular portion of the view.
You can try below code also in shared/event_box partial. It will work.
<% #events = Event.all %>
<% #events.each do |event| %>
<p><%= event.column_name %></p>
<% end %>
Related
Is it possible to generate a dynamic method using the strong parameter I get from my view?
In my view I will generate a different path according to the card the user clicks on. Then, in the controller I want to generate a dynamic method using the parameter obtained from the view, but I'm not sure how to write that. Thanks!
show.html.erb
<div class="branch-names">
<% #branches.each do |branch| %>
<div>
<%= image_tag "cat.jpeg" %>
<%= link_to "#{branch.name} Posts", send("#{branch.branch}_posts_path") %>
</div>
<% end %>
</div>
posts_controller.rb
def self.define_category(name)
define_method(name) do |params[:id]|
#posts = Post.where(category_id = params[:id])
end
end
define_category("#{params[:id]}")
You shouldn't define method based on user input. It may cause security issue, and for sure it causes performance penalty related to method cache invalidation.
Instead you can create one method that have an alternarive on params[:id] and then decide what to show to the user:
class MyController
def branches
case params[:id]
when('cat')
do_cat_stuff
when('dog')
do_dog_stuff
end
end
end
For having routes like /posts/cats you do not have to add dynamic methods. Think of branch like of an id of category:
routes:
resources :post_categories, only:[:index, :show]
view:
...
<%= link_to "#{branch.name} Posts", post_category_path(branch.branch) %>
PostCategories controller:
def show
#posts = Post.where(category_id: params[:id])
end
Also you can make posts a nested resource under categories and use a more RESTful structure with /post_categories/some_branch/posts mapping to posts#index
I'm trying to render a the index view inside my ruby-on-rails application. How do a I render the index view, from inside a view passing an array of things to display? Using the link_to.
I do not want to re-route to the controller, I just want to link_to a view passing it the variables it needs, how can I do this?
EDIT:
I am trying to create a page type functionality in the index of my article model. So I have around 400 articles for example, and when the index action in the article controller is called, it of course renders the index view which is calling a partial for each article in the '#articles array' passed on by article controller's index action.
So in the view, I'm trying to do something like:
<% count = 0 %>
<% #articles.each do |article| %>
<% if count <10 %>
<%= render partial: 'index_articles', locals: {article: article} %>
<% count = count + 1 %>
<% end %>
<% end %>
<% #articles = #articles.drop(10) %>
<% if #articles.any? %>
<%= link_to "Next", 'articles', locals: {#articles => #articles} %>
<% end %>
Thank you in advanced for all of your help.
You'll need to use the render command, probably with a partial:
<%= render "controller/index", collection: ["your", "array"], as: :object_name %>
You will have to call a controller action to generate this. You cannot simply load it on your screen, unless it was preloaded inside your javascript for something:
#View
<%= link_to "Index", controllers_path(ids: ["1","2"]), remote: true %>
#app/controllers/your_controller.rb
class YourController < ApplicationController
def index
#posts = request.xhr? Post.find(params[:ids]) : Post.all
respond_to do |format|
format.js #-> app/views/controller/index.js.erb
format.html
end
end
end
#app/views/controller/index.js.erb
$(".element").html("<%=j render 'index' %>");
There are several issues with this approach...
Flow
First of all, your flow of your app should be as structured as possible.
In short, if you're calling the index view inside another action, it's not the index view any more.
What you should look at is how to use a partial in your app:
#app/controller/views/_partial.html.erb
<%= post.title %>
This way, you can adapt your index view and your other page to use the partial in their respective action layouts:
#app/controller/views/index.html.erb
<%= render "partial", collection: #posts, as: :post %>
This will allow you to "reuse" code much in the way you want. This will be much more appropriate than trying to invoke other action/views.
-
Resources
Secondly, you'll want to look at how your app functions.
Your index view is meant to show all the items for a particular object. Whilst you're free to change this as you want, the fact remains that you have to keep some structure.
You should read up on the routes for your actions, and how they're meant to work in your application. This will give you some perspective on the resourceful nature of Rails routes, and how you'll have to call specific routes with specific actions.
Your problem is probably that the file needs to be named _index.html.erb. You can have another file named index.html.erb which just renders _index.html.erb.
If you need a full guide on using AJAX, look up the railscast. If you're not using AJAX and you just want to render it, then you don't use link_to. You just do <%= render :index %>.
I'm trying to render a view in a different controllers view but I'm getting:
undefined method `each' for nil:NilClass
I'm rendering the view in 'views/users/show' as:
<%= render :template => 'groups/index' %>
The view itself is under 'views/groups/index':
<% #groups.each do |group| %>
<li>
<%= group.name %>
<%= group.description %>
</li>
<% end %>
And my groups controller for index looks like this:
def index
#groups = Group.all
end
I think it's a problem with how i'm rendering the view since if I make an instance variable in my index controller and call it in the view it won't appear. There are entries in the Group table in my database.
Any help would be appreciated.
Thanks in advance.
I think it should be enough to replace the template: with a partial: parameter.
Try this:
<%= render partial: 'groups/index' %>
You will have to rename/copy groups/index.html.erb with groups/_index.html.erb
This only works for rendering a view, but will not implement the functionality of your GroupsController.
Edit
You will have to redefine the groups inside your UsersController
# UsersController
def index
#groups = Group.all
end
Depending on how many times you will need to present all these groups to your user, this can become hard to maintain. If you use it frequently, consider adding
# i.e. ApplicationController
def groups
Group.all
end
inside your ApplicationController (or some module you want to include in different controllers). Then you could call
# UsersController
def index
#groups = groups
end
and still <%= render partial: 'groups/index' %>
Change:
<%= render :template => 'groups/index' %>
To:
<%= render 'groups/index' %>
and make sure the file name of your index action is _index.html.erb and not index.html.erb.
EDIT
When you render a view, you are only rendering the template, this does invoke a request on your index action. You must define #groups in your initial view's action.
I'm a beginner at rails and thus far interplating data in views has been pretty straight forward. I've been introduced to something slightly new as far as how the controllers are setup and as a result I'm not sure how one would go about getting the data to present in the view.
First controller
class PagesController < ApplicationController
def index
#guestbook_entry = GuestbookEntry.new
render "welcome"
end
end
Second controller
class GuestbookEntriesController < ApplicationController
def create
GuestbookEntry.create(guestbook_entry_params)
redirect_to root_path, notice: "Thank you for your entry."
end
private
def guestbook_entry_params
params.require(:guestbook_entry).permit(:body)
end
end
And here is the welcome.html.erb
<h1>Welcome to My Guestbook</h1>
<br>
<%= image_tag("under_construction.gif") %>
<div id="guestbook-entries">
<p>Guestbook Entries:</p>
<ul>
</ul>
</div>
<%= form_for #guestbook_entry do |f| %>
<%= f.label :body, "Guestbook Entry:" %>
<%= f.text_area :body %>
<%= f.submit "Submit" %>
<% end %>
So it wants me to iterate through all the entries and display them on a welcome page that's located in view/pages/welcome.html.erb.
Up to this point I guess I've only been doing basic simple rails applications where the view corresponded with the controller, and followed the typical CRUD setup, where index would hold the #xxx = Xxxx.all and new/create would handle #xxx = Xxxx.new/create/build. I thought I could simply move the PageController's index action to create/new and do
def index
#guestbook_entry = GuestbookEntry.all
render "welcome"
end
To satisfy the test (it looks for render welcome in the index action)
This seems weird but again I admit, I'm a beginner.
If you want to list all the guest book entries on your root page you would do something like:
class PagesController < ApplicationController
def index
#guestbook_entry = GuestbookEntry.new
#guestbook_entries = GuestbookEntry.limit(10).all
render "welcome"
end
end
And in your view you would list them like:
<% if #guestbook_entries.any? %>
<div id="guestbook-entries">
<p>Guestbook Entries:</p>
<% #guestbook_entries.each do |entry| %>
<ul>
<li class="entry"><%= h(entry.body) %></li>
</ul>
<% end %>
</div>
<% end %>
The rest of you application is correct - you should be creating entries in GuestbookEntriesController#create. In many real life applications then the functionality of the standard new and edit actions can actually be a totally different controller.
I have a rails application that has 2 menu in which the menus changes depending on what page the users are currently visiting. Is there any way to tell rails that if a user is visiting this controller, no matter if the visitor is on the index,edit,create,update,delete method?
I am currently using a helper like so it and it indeed a bit messy.
def which_page
current_page?(root_path) ||
current_page?(skate_movies_path) ||
current_page?(new_skate_photos_path(#user)) ||
current_page?(skate_photos_path) ||
current_page?(skate_tricks_path)
end
In My view partial
<% if which_page %>
<%= default_menu %> #upload, #photos, #trick-tips, #goals
<% else %>
<%= skate_menu %> #dashboard, #shared-videos, #profile
<% end %>
The problem is this works but throughout the application I always find a page or two where it gives me a routing error. Any way to tell what controller the user is on and action without specifying ever action?
You could define a before_filter in your ApplicationController and name it set_menu
class ApplicationController < ActionController::Base
before_filter :set_menu
protected
def set_menu
#menu = 'default'
end
end
Then in each controller that you want to show a different menu for you would override set_menu, for example:
class SkateMoviesController < ApplicationController
protected
def set_menu
#menu = 'skate'
end
end
you could use the helper method action_name in set_menu to access the current action in the controller.
Then in your views:
<% if #menu == 'default' %>
<%= default_menu %>
<% else %>
<%= skate_menu %>
<% end %>