Refactoring acts_as_taggable suggestions? - ruby-on-rails

I have an application with a list of majors and each one is tagged with categories using the acts-as-taggable-on gem. I have a page where you can explore majors by category. So, you see the categories and grouped under the category is a list of the majors.
My categories_controller.rb file:
def index
#creative = Major.tagged_with("creative arts")
#engineering = Major.tagged_with("engineering and technology")
#mechanics = Major.tagged_with("mechanics and construction")
#transportation = Major.tagged_with("transportation")
#science = Major.tagged_with("science")
#math = Major.tagged_with("math")
#resources = Major.tagged_with("natural resources")
#healthcare = Major.tagged_with("health care")
#social_sciences = Major.tagged_with("social sciences")
#education = Major.tagged_with("education")
#law = Major.tagged_with("law")
#management = Major.tagged_with("management and marketing")
#administrative = Major.tagged_with("administrative and clerical")
#services = Major.tagged_with("services")
#tags = Major.tag_counts
end
You can see the duplication. This is compounded on the view template.
Here's part of the index.html.erb page:
<!-- Creative Arts -->
<h2 class="major-categories-landing">Creative Arts</h2>
<% #creative.sample(10).each do |creative| %>
<%= link_to creative, class: 'span2 category-landing' do %>
<%= image_tag creative.image(:similar), class: 'img-polaroid', id: 'category-landing-list' %>
<p class="category-landing-list-name"><%= creative.name %></p>
<% end %>
<% end %>
<%= link_to "View all #{#creative.count} majors in this category.", category_path("creative arts"), class: "view-category-show-page" %>
<!-- Social Sciences -->
<h2 class="major-categories-landing">Social Sciences</h2>
<% #social_sciences.sample(10).each do |ss| %>
<%= link_to ss, class: 'span2 category-landing' do %>
<%= image_tag ss.image(:similar), class: 'img-polaroid', id: 'category-landing-list' %>
<p class="category-landing-list-name"><%= ss.name %></p>
<% end %>
<% end %>
<%= link_to "View all #{#social_sciences.count} majors in this category.", category_path("social sciences"), class: "view-category-show-page" %>
and so on for each category. I have tried #category = Major.tagged_with(params[:tag]) and many variations to that to no avail. This is my first time working with acts_as_taggable_on and although I've read the documentation over and over I can't quite figure this out.
I hope to extend this out throughout the application and so I want to figure it out now before I get a lot duplicate code. Thanks for sharing any ideas or suggestions!!
I am running a rails 3.2.11 app.
UPDATE
Here's how much better this is now:
My categories_controller.rb file:
def index
#major_categories = ["creative arts", "social sciences", "science", ....]
end
My index.html.erb page:
<% #major_categories.each do |c| %>
<!-- Title and blue strip -->
<div class="category-strip">
<div class="container">
<h2 class="major-categories-landing"><%= c %></h2>
</div>
</div>
<!-- Show Each Major in this Category -->
<div class="container">
<div class="row-fluid">
<% Major.tagged_with(c).order('RANDOM()').limit(10).each do |major| %>
<%= link_to major, class: 'span2 category-landing' do %>
<%= image_tag major.image(:similar), class: 'img-polaroid' %>
<p class="category-landing-list-name"><%= major.name %></p>
<% end %>
<% end %>
</div>
<!-- Link to View All Majors -->
<div class="row-fluid">
<div class="view-all-category">
<%= link_to "View all #{Major.tagged_with(c).count} majors in this category.", category_path(c), class: "view-category-show-page" %>
</div>
</div>
</div>
<% end %>

I would do something like this:
# in categories_controller.rb
def index
#categories = ["creative arts", "engineering and technology",
"mechanics and construction", ...]
end
# in index.html.erb
<%= render partial: "category", collection: #categories %>
# in _category.html.erb
<h2 class="major-categories-landing"><%= category.titleize %></h2>
<% Major.tagged_with(category).order('rand()').limit(10).each do |major| %>
<%= link_to major, class: 'span2 category-landing' do %>
<%= image_tag major.image(:similar), class: 'img-polaroid',
id: 'category-landing-list' %>
<p class="category-landing-list-name"><%= major.name %></p>
<% end %>
<% end %>
<%= link_to "View all #{Major.tagged_with(category).count} majors in this category.",
category_path(category), class: "view-category-show-page" %>
Btw: The link to each major is invalid html. A link (because a it is an inline element) should not contain a paragraph (because p is a box element). Furthermore each link for each category would have the same id, but ids must be unique in each html document.

Related

I am newbie in ruby on rails and trying to link into "changelog_settings.html.erb" page, but in the end, it redirect to different page

controller:
def add_changelog
changlog_alert= params[:program][:changlog_alert]
#program.update(changlog_alert: changlog_alert)
flash[:notice] = "Changelog Updated Successfully."
redirect_to portal_admins_changelog_settings_path(#enterprise, #program)
end
routes:
namespace :admins do
get "changelog_settings"
post "add_changelog"
end
changelog_settings.html.erb
<div class="large-12 small-12 columns settings_menu_content px-6 white_shadow p-5">
<%= render partial: "portal/admins/dashboard_settings/changelog" %>
</div>
_changelog.html.erb
<%= form_for #program, url: portal_admins_add_changelog_path(#enterprise, #program), method: :post do |f| %>
<%= f.text_area :changelog_alert, value: #program.changelog_alert, rows: "3" %>
<div style="text-align: right;">
<p id="limit" style="text-align: right;margin-top: -10px;color: gray;"> <%= #program.changelog_alert ? (300 - #program.changelog_alert.split(" ").count) : '300' %> Words Remaining </p>
<%= f.submit "Save Changes", class: "btn btn-blue" %>
</div>
<% end %>
Rake route
portal_admins_changelog_settings GET /app/:enterprise_id/:program_id/admins
changelog_settings(.:format) portal/admins#changelog_settings {:subdomain=>"portal"}
So mainly this _changelog.html.erb file trying to show and seems like route also fine but everytime it goes to different page

Button not calling a controller in ruby

I have a screen where a user can select differente kinds of plans for his account. Like this:
#plans
<% Plan.all.order(:amount).each do |plan| %>
<%= render 'shared/plan_detail', {plan: plan, button_text: 'Choose this' } %>
<% end %>
#plan_detail
<div class="plan-details">
<header class= <%= plan.css %> >
<h3><%= plan.name %></h3>
<small><%= plan.visibility %></small>
<p><%= plan.card_description.html_safe %></p>
<span class="plan-price"><sup>$</sup><%= plan.amount.to_s %></span>
</header>
<article>
<%= plan.features_description.html_safe %>
<%= link_to button_text, {:controller => "accounts", :action => "update_plan", :plan => plan.id }, title: button_text, :class=>"btn btn-md btn-block btn-outline-green dialog-open" %>
</article>
</div><!-- end plan details -->
And In my controller i have:
#accounts_controller.rb
def update_plan
#plan = Plan.find(params[:plan])
current_user.plan = #plan
current_user.save
end
My routes its like this
get '/account/plans', to: 'accounts#plans', as: :update_plan
put '/account/plans', to: 'accounts#update_plan'
But I click on the button, and nothing happens. What Im doing wrong here?
This is a long shot, but seeing that your link has dialog-open I wouldn't be surprised if there was some Javascript preventing your link from working. In order to debug this further I would
a) Check browser's Javascript console for any errors
b) Remove the dialog-open class to see what happens

Rails retrieving all records in show controller

In my rails category show controller for categories I have it setup like this
def show
#categories = Category.find_by(params[:name])
end
But when I visit this controller it returns all records of products found in the category instead of single category.
Here is the code in my view controller for category
<div class="grid">
<% #categories.products.each do |product| %>
<%= link_to product_path(id: product.slug, category_name: product.category.name), class: "card" do %>
<div class="product-image">
<%= image_tag product.productpic.url if product.productpic? %>
</div>
<div class="product-text">
<h2 class="product-title"> <%= product.name %></h2>
<h3 class="product-price">£<%= product.price %></h3>
</div>
<% end %>
<% end %>
</div>
What am i doing wrong here?
First of all, for security purposes, you should never trust the params hash to retrieve records. Rails will "make the data safe" if you use a hash as your arguments. Use this code below:
def show
#category = Category.find_by(name: params[:name])
end
Second, usually on a show page, you only want to retrieve one record and therefore the variable should be named as singular. I corrected that above.
Third, it helps if you use proper indenting when posting examples. It makes it easier for us to help you.
Fourth, the line below (I changed #categories to #category) is basically saying: "Now that I have this single category, find all the products associated with it in the products table and put them into the |product| variable for iteration"
<% #category.products.each do |product| %>
I'm not sure what you want to do with the category, but if you keep this line of code, it will always show you all the products. Maybe you only want to show the most recent 3, in which case you could do something like this:
In your controller:
def show
#category = Category.find_by(name: params[:name])
#recent_products = #category.products.order(created_at: :desc).limit(3)
end
In your view:
<div class="grid">
<% #recent_products.each do |product| %>
<%= link_to product_path(id: product.slug, category_name: product.category.name), class: "card" do %>
<div class="product-image">
<%= image_tag product.productpic.url if product.productpic? %>
</div>
<div class="product-text">
<h2 class="product-title"> <%= product.name %></h2>
<h3 class="product-price">£<%= product.price %></h3>
</div>
<% end %>
<% end %>
</div>
You can do this way
in your controller you can write this code
def show
#category = Category.find_by_name(params[:name])
end
and in your view it will work
<div class="grid">
<% #category.products.each do |product|%>
// place your code what you want to display
<% end %>
</div>
I hope it would help you and still if you have any concern please let me know.

Query "where" with ruby on rails

I've in my app, posts as ideas, and these ideas belongs to an activity and a status.
And I want to sort them by activity for one status so I did in my controller
#idees_en_place = Idee.where(statut_id= "2")
#activites = Activite.all
And in my view :
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% #idees_en_place.where(activite_id = activite.id).limit(3).each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
But that doesn't work, in each part of an activity the ideas are not sorted.
I think it's a little mistake but I don't know how to resolve this
#idees_en_place = Idee.where(statut_id= "2")
There are two problems with this code.
First, id is a Integer type (unless you've defined it as String).
Second, its a key value you pass to where clause, and you pass these either as
:status_id => 2 # old hashrocket syntax
or
status_id: 2 # new syntax
The same goes with this part
#idees_en_place.where(activite_id = activite.id)
it should be
#idees_en_place.where(activite_id: activite.id)
In Controller
#idees_en_place = Idee.where(statut_id: 2)
#activites = Activite.all
In View
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% #idees_en_place.where(activite_id: activite.id).limit(3).each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
I just wanna point out that you will run into an N+1 queries issue, to avoid this you should preload every thing, instead of doing queries in the views.
The controller:
#change if the association name is different
#activites = Activite.includes(:idees)
The view
<% #activites.each do |activite| %>
<div class="idee en-place col-lg-5" style="background:#<%= activite.color%>">
<h2><%= activite.name %></h2>
<p>
<% activitie.idees[0..2].each do |idee| %>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>
<% end %>
Notes:
I've used the [0..2] format because I wanted to avoid ActiveRecord from doing a new query, another method would be limiting the query using something like this
#activites = Activite.includes(:idees).merge(Idee.limit(3))
Then you won't need to use any limitation in the views, but I haven't tested this, don't have access on a rails machine right now.
I think that the following code will help you:
Since your Idee belong to activity and status that's why you have activity_id and status_id in your Idee table.
you may find out all the idee for a status by using:
Idee.where(:status_id => 2)
and you can sort Idee in Asc or desc order by using order
idees = Idee.join(:activity).where(:status_id => 2).order(:activity_id => :asc)
idees = Idee.join(:activity).where(:status_id => 2).order(:activity_id => :desc)
<% activity_id = -1%>
<#idees.each do |idee| %>
<div class="idee en-place col-lg-5" style="background:#<%= idee.activite.color%>">
<h2><%= idee.activity.name %></h2>
<p>
<% if activity_id != idee.activity_id %>
<% activity_id = idee.activity.id %>
<% counter = 0 %>
<% end %>
<% if counter < 3 %>
<% counter = counter + 1%>
<div class="idee">
<h6><%= link_to idee.title, idee %></h6>
</div>
<% end %>
</p>
</div>

Need to group shows by day in a rails Application

I am trying to get shows on a certain day to show up just for that day and I would like to be able to see what shows are going on in the next couple of days as well.
The View:
<% t = Time.new %>
<h2 class="center" style="color:#2A2C2B"><u><%= t.strftime("%A, %B %e") %></u></h2>
<% #clubs.each do |club| %>
<!-- # <% club.shows.future.present? %> -->
<h1 class="club"><%= link_to club.name, club.website %> </h1>
<% club.shows.future.each do |show| %>
<h3 class="center"><%= show.pretty_start_time %></h3>
<% show.comedians.each do |comedian| %>
<div>
<ol>
<h4 class="comedian"><%= link_to simple_format(comedian.name),comedian_path(comedian) %></h4>
<p class="bio"><u><%= comedian.bio %></u></p>
</ol>
</div>
<% end %>
<% end %>
<%- end -%>
The Comedy Hub Controller:
class ComedyHubsController < ApplicationController
def show
#clubs = ComedyClub.all
end
end
This might work:
<% shows.goup_by{|show| show.date}.each do |dategroup| %>
<# do something to indicated the group up here? %>
<%= dategroup.each do |show| %>
<li> <%# put details here %> </li>
<% end %>
<% end %>
Assuming, there is a DateTime column on Show called start and the ComedyClub model has a a has_many :shows and the Show model has the belongs_to :comedy_club association defined
In your ComedayHubsController#show method, do the following query
#clubs = ComedyClub.join(:shows).where("shows.start >=?", DateTime.now).order("shows.start ASC")
Now only clubs with shows in the future will be sent to the view and already ordered by start.

Resources