Acts as taggable on Rails - ruby-on-rails

How can I make an index route/action to see all the tags that I've created!, I'm using the gem at https://github.com/mbleigh/acts-as-taggable-on
Thanks.

Use ActsAsTaggableOn::Tag.all to list all the tags, for example
# tags_controller.rb
def index
#tags = ActsAsTaggableOn::Tag.all
end
# tags/index.html.erb
<% #tags.each do |tag| %>
some html to display
<% end %>
Of course if you don't have a tags controller you will have to create one, and the routes in routes.rb. You can use the rails generate controller tags index command if you want. Run rake routes to see what the routes are.
You can take a look at the actual Tag model here: https://github.com/mbleigh/acts-as-taggable-on/blob/master/lib/acts_as_taggable_on/tag.rb
And the fields available for Tag you can find in your db/schema.rb file.

Related

ruby on rails will_paginate change default link

In the routes.rb I set lists#index as the root:
root to: "lists#index"
I would like will_paginate to create page hrefs pointing to /?page=# instead of /lists?page=#. To create the paginate links I have the following line in the "lists#index" file:
<%= will_paginate #lists %>
The solution was indeed a custom renderer. Thanks Ayush!
The following helped me to solve it: how-to-customize-the-will-paginate-links-with-images
I created a file: app/helpers/will_paginate_helper.rb with the following content:
module WillPaginateHelper
class RootedLinkRenderer < WillPaginate::ActionView::LinkRenderer
protected
def link(text, target, attributes = {})
if target.is_a? Fixnum
attributes[:rel] = ""
target = "/?page=#{target}"
end
attributes[:href] = target
tag(:a, text, attributes)
end
end
end
Finally, I updated the index file and replaced:
<%= will_paginate #lists %>
with:
<%= will_paginate #lists, renderer: WillPaginateHelper::RootedLinkRenderer %>
So the href is http://localhost:3000/?page=2 and not http://localhost:3000/lists?page=2.
What I understand from your question that you are trying to create a custom renderer, although I have never used it, but for that you need to override the link method of renderer.
here is the link to the original code might be of some help -
https://github.com/voormedia/paginary/blob/master/lib/paginary/helpers/pagination_helper.rb
In this particular case the links are influenced by the order of the routing instructions in the routes.rb file.
If you place the line
root to: "lists#index"
at the top of routes.rb then will_paginate will generate links to /?page=# without the need for a custom renderer.
This can be found in the FAQs for the module in coursera.

How to parameterize url slug with acts as taggable

I am using rails 4 and the acts-as-taggable-on gem. I am showing the tags in my view like this:
<p id="tags">Tags: <%= raw #item.tag_list.map { |t| link_to t, tag_path(t.parameterize) }.join(', ') %></p>
If I create a tag with a space "cool tag" it creates the url /tags/cool-tag which is how I want the url to look like for tags with spaces in the tag name.
However, this link leads to nowhere. The actual link that gets created from my routes file looks like /tags/cool%20tag.
The corresponding line in my routes file looks like this:
get 'tags/:tag', to: 'items#tag', as: :tag
and items_controller.rb:
class ItemsController < InheritedResources::Base
def tag
#tag = Tag.find_by_name(params[:tag])
#tagged_items = Item.tagged_with(params[:tag])
end
Is there a way to use parameterize on the other end in my routes so that /tags/cool-tag exists instead of /tags/cool%20tag?

Ruby on Rails layouts and rendering

I'm new to RoR and I'm a little bit confused with Rails MWC. I feel like I misunderstand something.
For example, I want to have home page where I could render top 5 articles and top 5 products. Products and articles have no relations at all, it is totally separate data.
So what I try to do is, i crate 2 sacffolds products and articles, and 1 controller for home page. I root to homepage controller. Then in homepage template i try to render products and article template. I get an error that methods which are used in products and articles controllers are undefined.
I don't understand where is problem. Is this kind of template rendering one template inside another is not Rails convention. Or I have bugs in my code.
I don't see your code but in this case I'm quite sure you have bugs in it.
app/controllers/home_controller.rb
class HomeController < ApplicationController
def index
#products = Product.top5 # Your logic to fetch top 5
#articles = Article.top5
end
end
app/views/home/index.html.erb
<% #products.each do |product| %>
<%= product.name %>
<% end %>
<% #articles.each do |article| %>
<%= article.name %>
<% end %>
This is perfectly fine, I've done that multiple times. Consider that in Rails you don't have any relation between controller and models, there are convention but Rails controller is not bound at all to any model
First, you need to instantiate your variables #products and #articles (this is an example) on your controller method. Then you can render the view.
Pay attention to add an # before. Only variables with an # will be available on your rendering view.
By default, when you call a GET for /products you'll arrive on the index method. At the end of this method, if not any view is specified, Rails will render views/products/index. In this view, you'll access all variables instantiate with an # and do whatever you want with.
First, yes, a template rendering another controller's template (not a partial) is not within Rails conventions.
A scaffold is a "single-resource" controller: it takes your model definition and generates a basic controller for editing and displaying that particular model (i. e., Product).
What you really need to do is use the two models you've generated in the home page controller, kinda like this:
class HomePageController < ApplicationController
def index
#articles = Article.top_5
#products = Product.top_5
# Render the #articles and #products in the view.
end
end

Rails routing causing error?

I'm super new to Ruby/Rails and need help with an assignment I'm working on. I'm supposed to add native advertising to Bloccit (project i'm working on for class) in the form of sponsored links. Any help would be very appreciated :)
What needs to be done:
1) Create a new model called Advertisement. It should have the following attributes: title:string, copy:text, price:integer.
2) Generate a controller for the new advertisement model with index and show actions. Should the controller class and file names have a singular (advertisement) or plural (advertisements) prefix? Be consistent with the naming pattern used for the posts controller class and file generated earlier.
3) Update routes.rb to use resourceful routing for Advertisement.
4) Complete the index and show actions in AdvertisementsController.
5) Update the Advertisement index and show views.
This is what I've got:
First thing, create model like so
rails g model Advertisements title:string, copy:text, price:integer
Then, create controller like so
rails g controller Advertisements index show
Resourceful routing:
Rails.application.routes.draw do
resources :advertisement
resources :posts
get 'about' => 'welcome#about'
root to: 'welcome#index'
end
Index and show actions:
class AdvertisementController < ApplicationController
def index
#advertisements = Advertisement.all
end
def show
#advertisements = Advertisement.find(params[:id])
end
end
Index view:
<h1>Advertisements</h1>
<% #advertisements.each do |advertisement| %>
<% end %>
Show view:
<h1><%= #advertisements.title %></h1>
<p><%= #advertisements.copy %></p>
<p><%= #advertisements.price %></p>
When I go to localhost:3000/advertisement I see a blank page page with "Advertisements" at the top. When I go to to localhost:3000/advertisement/index I see an error message:
Couldn't find Advertisement with 'id'=index
def show
#advertisements = Advertisement.find(params[:id]) #second line highlighted in red
end
end
Why I can't I view an individual advertisement or see an index of all advertisements like I'm supposed to?
You are seeing an index of all the Advertisements when you see the page with just Advertisements at the top, it isn't repeating & printing any because none exist.
Not being able to see just one is because the route defaults to
localhost:3000/advertisements/:id
So it's trying to lookup an Advertisement with the :id of "index", which most likely doesn't exist.
Try to create an advertisement
You don't appear to be outputting anything for each advertisement in your index view and are just looping through the advertisements:
<h1>Advertisements</h1>
<% #advertisements.each do |advertisement| %>
<% end %>
Inside the loop, you will need to add mark up and ERB that you wish to see for each advertisement.
You can seed your database or create advertisements through the Rails console to test. As Alfred implies, you should be able to see id=1 at:
localhost:3000/advertisements/1
Minor point, for show action and view, #advertisement (singular) makes more sense semantically (you are showing a single advertisement).
You will find that rails is your friend when creating the Routes, Controllers and views you are looking for. Here is the simpliest way to solve you problem:
In terminal cd into your rails program and then:
rails g scaffold advertisement title:string, copy:text, price:integer
press enter and then rake db:migrate.
When you go to localhost:3000/advertisements you on on the index for advertisements localhost:3000/advertisements/[some :id] is the show page for a particular advertisement
additionally in your index view you have to use the block variable you are creating which in this case is advertisement to call the attributes you want on the page:
<%#advertisements.each do |advertisement|%>
(Which is all the advertisement being looped)
<%= advertisement.title %>
<%= advertisement.copy %>
<%= advertisement.price %>
<% end%>
And you will see a display of individual advertisements with their respective elements
You forgot to Seed some Data.
In you file: db/seeds.rb add:
# Create Advertisements
10.times do
Advertisement.create!(
title: Faker::Internet.domain_name,
copy: Faker::Company.catch_phrase,
price: 0
)
end
Then enter this to your terminal: rake db:seed
In case you didn't do it, rake db:migrate
It should be working now.

Rails will_paginate - how to make nicer route?

I have on the homepage list of articles that are listed with using will_paginate gem.
Everything works well, but there is one thing I would want to improve - on the homepage, the data are loaded into home controller and index action.
So, when I load my website - www.website.com, data are loaded into home/index. When I click on the pagination link for the second page, the link is www.website.com/home/index?page=2. I would like to see there in the best way www.website.com/page/2 (or www.website.com/?page=2).
Basically, the point is to remove from the URL /home/index - is there any way to do this?
Thanks
You may do it this way - add this class to some helper module, for example app/helpers/application_helper.rb:
module ApplicationHelper
class SmartLinkRenderer < WillPaginate::ActionView::LinkRenderer
protected
def link(text, target, attributes = {})
if target.is_a? Fixnum
attributes[:rel] = rel_value(target)
target = url(target)
end
attributes[:href] = target.gsub(/[?&]page=(\d+)/,'/page/\1')
tag(:a, text, attributes)
end
end
end
You may customize it according to your needs, for example do
attributes[:href] = target.gsub(/home\/index/,'')
or whatever. And then you may do this in your views:
<%= will_paginate #items, :renderer => 'ApplicationHelper::SmartLinkRenderer' %>
Try this
root to: 'home#index'
in you config/routes.rb file
EDIT
to be able to route these kind of requests:
www.website.com/page/2
add this to routes.rb:
match "page/:page" => "your_root_controller#index"
this way :page will be in your params hash.
and for example index method to view your Message model can be:
def index
#messages = Messages.paginate(page: params[:page])
end
hope that can help. for more information please refer to RoR routing

Resources