Ruby on Rails global categories block - ruby-on-rails

I am new to ROR and I don't understand how can I make global template which I could put in any other template. For example I have categories module and would like to create sidebar navigation and put it at homepage template. I tried to do it this way, but categories controller method side_nav is never called. Is this good practice for this type of problem or should i do it different way?
categories/categories_controller.rb
def side_nav
#categories = Category.all
end
categories/_side_nav.html.erb
<ul class="list-unstyled">
<% categories.each do |category| %>
<li><%= link_to category.title, category.title.downcase %></li>
<% end %>
</ul>
homepage/index.html.erb
<%= render 'categories/side_nav' %>

You may look at layout/application file. It's global layout in your custom project by default. And you can provide your custom layouts in your contollers.
http://guides.rubyonrails.org/layouts_and_rendering.html

Related

Rails - Display all questions by category

I have question and category model. Question model has category_id column.
class Question
belongs_to :category
end
class Category
has_many :questions
end
In my controller I have this:
def index
#categories = Category.all
#questions = Question.all
end
I would like to display all categories and all questions that belongs_to specified category. Also, I would like to display question numbers below each category and made links of them and later it will open new page with clicked question.
This is how I tried to do that:
<% #categories.each do |category| %>
<h1><%= category.name %></h1>
<% #questions.each do |question| %>
<ul>
<li><%= link_to question.id %></li>
</ul>
<% end %>
<% end %>
It should look like this but I get stuck:
Category1
1 2 3 4
Category2
1 2 3 4
Question: How to achieve that I display questions like is show above?
You can do it this way:
Controller:
def index
#categories = Category.all
end
View:
<% #categories.each do |category| %>
<h1><%= category.name %></h1>
<% category.questions.each do |question| %>
<ul>
<li><%= link_to question.id, question_path %></li>
</ul>
<% end %>
<% end %>
Since you said you want to display all of the categories, and the questions that belong to each of those categories, I'm assuming that the index action that you pasted in comes from your categories_controller.
One solution I can think of would be to change the instance variables inside your index. I don't really see a purpose for having the instance variable that references all of your Question objects. This is the one I'm talking about:
#questions = Question.all
Yea, get rid of that. You should be fine with just
#categories = Category.all
Since you want to display all of your categories, that instance variable is necessary. And since you mentioned you want to also display all of the questions that belong to each category, that instance variable is sufficient with the right view. You were on the right track, but instead, just use the #categories instance variable; forget about #questions. Here is what your view should probably look like (you were on the right track above):
<% #categories.each do |category| %>
<h1><%= category.name %></h1>
<% category.questions.each do |question| %>
<ul>
<li><%= link_to question.id, question_path %></li>
</ul>
<% end %>
<% end %>
Also note that in that first line of code, when you start a block, you don't need the <%= , You only need the <%. That's because that first line of the block is purely ruby in itself, it isn't actually getting printed to the resulting html.
Hope I helped a little bit!
* Also: I saw another answer on here which is missing something: When you use the <%= link_to %> helper, you need to specify the first argument which is the resulting markup (In this case you wanted the question.id) , AND ALSO A SECOND ARGUMENT, which is the path for the link to follow *

Setting a variable within a link_to, in rails 4

I am trying to set variables in a series of link_to links, so that each link is associated with a value.
On one page I have a loop which creates a list of links from values in my database:
<ul>
<% #alldata.each do |x| %>
<li><%= link_to "#{x.name}", charts_path %></li>
<% end %>
</ul>
The charts_path links to a view which displays a chartkick graph:
<%= line_chart #data.group("year").sum("magnitude") %>
which gets its data from a controller saying:
def graphdata(x)
#data = Model.all.where(name: x).select("magnitude, year")
end
def charts(?variable)
#data = graphdata(?variable)
end
I would like to alter my list loop to set ?variable to x.name. For example something like:
<li><%= link_to "#{x.name}", charts_path, ?variable = "#{x.name}" %></li>
So that I have a list of links, that route to different charts with data specific to that link.
I could define a specific view for every single name:
def chart1
#data = graphdata("name1")
end
def chart2
#data = graphdata("name2")
end
But that seems like very bad programming...
I'm sorry if this question is poor, I'm extremely new to programming.
Any assistance would be greatly appreciated!
Thank you
Try Using this Code.
<%= link_to "#{x.name}", charts_path(x.name) %>
If I understand correctly, you want to pass the name of x as a querystring variable. You can easily do this with the charts_path helper:
<%= link_to "#{x.name}", charts_path(variable: x.name) %>
charts_path accepts a hash that will be passed with the request
I encountered the similar state where I got my module worked with the following method
`<%= link_to n.subject, notifications_message_path(notification_id: n.id)%>`

Dynamic data in rails partial view

I've just started to use Partials in my rails application, at the moment i have the following code in my application.html.erb
<%= render 'categories/categorieslist' %>
This links to _categorieslist.html.erb in my views/categories/ folder
At the moment this partial contains hard coded hyperlinks
<ul class="unstyled">
<li style="padding-bottom:5px">Item A»</li>
<li style="padding-bottom:5px">Item B»</li>
</ul>
My aim is to have these categories coming from the database, e.g
<ul class="unstyled">
<% #categories.each do |category| %>
<li style="padding-bottom:5px"><%= category.name %> » </li>
<% end %>
</ul>
I have tried adding a categorieslist method in the categories controller e.g
def categorieslist
#categories = Category.all
respond_to do |format|
format.html # index.html.erb
format.json { render json: #categories }
end
end
but this is not being called by the partial (and i don't feel this is even the correct way to do it), and is showing the error
NoMethodError in Store#index
on the line <% #categories.each do |category| %>
My question is how do i pass into the partial in the application.html.erb file, the categories object that usually would come from a controller method in the categories controller?
Any help would be great.
You can send locales with your partial call in your view and pass variables to that partial.
For example (this is a partial shortcut):
Your view from which you call the partial
<%= render 'categories/categorieslist', :all_categories => #categories %>
Your partial categories/_categorieslist.html.erb (note there is no # with the variable)
<ul class="unstyled">
<% all_categories.each do |category| %>
<li style="padding-bottom:5px"><%= category.name %> » </li>
<% end %>
</ul>
For further information (and the long version), see 3.4.4 Passing Local Variables in the Rails Guides.
I'd use a collection for this:
<%= render 'categories/categorieslist', :collection => #categories, :as => :category %>
This renders a collection of items. In this case, all the categories. You can also pass it a custom name with the :as => .
Then in your partial you only include the stuff you want the items in the collection to render:
<li style="padding-bottom:5px"><%= category.name %> » </li>
The -ul- isn't included as it would be rendered multiple times. You'll need to wrap it around your render tag.
The result is the same as the suggestion #timbrandes outlined, (check out docs he linked to).
I've heard :collection gives you performance improvements.
http://rails-bestpractices.com/posts/38-use-render-collection-rails-3-when-possible
That's not the right way to do it, and your question is rather confusing.
I'd say that you still have to read a rails book. You seem to be still a bit too fresh
Anyway, controller methods usually represent http requests. And they are invoked accordingly to what is defined in the config/routes file. Views (*.erb) do not usually invoke controller methods. If they do so, they do it through an ajax request.
Data is passed from actions to the views through controllers instance variables.
If you want to invoke any methods within the views, they should be defined in helpers. Still, the only data they will manipulate is the one passed from controllers as instance variables.

is it possible to access value from a model databasetable in the application.html.erb?

im trying to make a app
with users
this users can join multiple groups - every group has the same menu on the page
their group page is accessable about group/1 or group/2
so i wanted to put the the menu in the application.html.erb, with lnks depending on the group.id - but i dont know how to acces this id in the application.html.erb
This is often done using content_for in the layout. Let's say you want your menu in a certain div in application.html.erb:
# application.html.erb
<div id="menu_div>
<ul>
... etc ...
</ul>
</div>
Replace the inner content with a yield statement:
<div id="menu_div>
<%= yield :group_menu %>
</div>
Then in the view template add the content_for block:
# page
<% content_for :group_menu do %>
<ul>
... etc ...
</ul>
<% end %>
Each page template can then define its own menu code in a content_for block. This can be further generalized by using a helper method in the block and passing in instance variables.
EDIT
Assuming #group is assigned in the controller, you might do something like:
<% content_for :group_menu do %>
<%= show_me_the_menu(#group) %>
<% end %>
and in the helper (obviously contrived example):
def show_me_the_menu(group)
content_tag :ul do
group.users.collect do |user|
concat(content_tag(:li, user.some_method))
end
end
end
The correct approach would be to set this in ApplicationController via before_filter and just use it as an instance variable in views.
So in controller set something like #links = some logic where you calculate your links based on current user.
In view you do something like:
<ul>
<%- for link in #links -%>
<li><%= link.title =>
<%- end -%.
</ul>
Of course, you set your #links in ApplicationController only if you want your links to be available to all your controllers/views, which I think you do.
Rails Cells could also be used here http://cells.rubyforge.org/
i solved my problem in a different way now. i created in the group model a "menu" and this i render partial in the application.html.erb

Multiple views in Rails

I have the following problem:
In Rails I have two Objects: Categories and Items
One category has many items and one item belongs to one category.
Okay. There are no problems.
But now, I want to display all existing categories in a sidebar on every page in my project.
I tried to do display them like:
<div class="sidebar">
<% #categories.each do |category| %>
<p><%= link_to category.title, category %></p>
<% end %>
</div>
My root controller is categories. On my starting page the code above will work without any problems.
But when I click on a category I get the following exception:
*You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.each*
Extracted source (around line #2):
2: <% #categories.each do |category| %>
How can I fix this problem?
Sorry for my bad English!
You forget to set the #categories variable in the controller.
You can either load the #categories in every action you need to display the sidebar or delegate the request to the view without setting an instance variable.
# in the controller
def action
#categories = ...
end
# or in the view
<div class="sidebar">
<% Category.all.each do |category| %>
<p><%= link_to category.title, category %></p>
<% end %>
</div>
If the code spans over multiple views/controllers, I would suggest you to extract the statement in a before_filter and/or a partial.

Resources