I am trying to achieve an unordered list of "Categories" in which if you click on a particular Category, all the photos(jags) that belong to that Category show on the screen. My view that includes the categories is:
<div id = "Categories">
<h2>Categories</h2>
<ul><% #cat.each do |c| %>
<li><%=link_to c.name, c,:controller => "category", :action => "show" %>
</li>
<% end %>
</ul>
my Category controller is:
def show
#jags = Jag.where("category_id = params[:id]")
if #jags.empty?
flash[:notice] = "No jags in this Category"
end
end
and lastly my show view is:
<%= render 'nav' %>
<div><% #jags.each do |j| %>
<%= image_tag j.image_url(:thumb)%>
<% end %>
</div>
The problem i am having is that I dont know how do i pass on my "particular category"(c) in the first view to the Category controller.
I tried making c an instance variable(#c) which apparently i cant do[formal argument cannot be an instance variable
'); #cat.each do |#c| ;#output_buffer.safe_concat('].
If I run this code I get an SQLlite error[SQLite3::SQLException: near "[:id]": syntax error: SELECT COUNT(*) FROM "jags" WHERE (category_id = params[:id])].
If you use RESTful controllers this should be enough:
<div id = "Categories">
<h2>Categories</h2>
<ul>
<% #cat.each do |c| %>
<li><%=link_to c.name, c %></li>
<% end %>
</ul>
Seeing as you're getting the ID for the Category in the controller, then you can just do
#category = Category.find params[:id]
in your controller. Also, clean up your link_to helper as per below.
Related
I have seven different assignment objects. I'm currently iterating through each instance and then I iterating through the users of each assignment. I'm trying to designate the users to the assignment. I have a has_many through table that assigns the user to the assignment. But, my problem right now is that it keeps selecting the first assignment when I'm trying to select the fourth assignment. The way I'm iterating with the HTML is wrong but I can't seem to figure out what I'm doing? Here is my HTML.
HTML:
<div class="assignments">
<% #assignments.each do |assignment| %>
<ul>
<li><%= link_to assignment.name, account_assignment_path(assignment) %></li>
<%= link_to "designate Worker", "#designate", class: "button", data: { designate_worker: "" } %>
<div id="workers-modal", class="modal--worker hidden">
<% #account.account_workers.each do |worker| %>
<ul>
<li><%= link_to worker.name, designate_account_assignment_path(assignment, user_id: worker.id) %></li>
</ul>
<% end %>
</div>
</ul>
<% end %>
</div>
As you can see I'm iterating through all the assignment on the current account. Then, I'm iterating through all the users on the current account. Then, I'm trying to select the particular assignment by the id and the user by the id and create a relationship between the two, But from the UI I can't select any assignment but the first one. I think this has something to do with the way I'm iterating but I don't know for sure.
Controller:
def designate
designated_user = current_account.users.find_by(id: params[:user_id])
membership = designated_user.assignment_relationships.find_or_create_by(assignment_id: params[:id])
membership.update!(designated: true)
flash[:notice] = "Successfully designated the user"
redirect_to root_path
end
As you can see. The second line in the method looks for the assignment_id with the params[:id]. Right now it only comes in as :id => "1", when I'm trying to get :id => "2" or "4"
Let me know if you need to see any other code. Thanks!
Do you really want to start a new list for each assignment and each worker. If you inspect the view, do you see each of the assignments with different ids? Try amending the view so the unordered list tags are outside the each loop:
<div class="assignments">
<ul>
<% #assignments.each do |assignment| %>
<li><%= link_to assignment.name, account_assignment_path(assignment) %></li>
<%= link_to "designate Worker", "#designate", class: "button", data: { designate_worker: "" } %>
<div id="workers-modal", class="modal--worker hidden">
<ul>
<% #account.account_workers.each do |worker| %>
<li><%= link_to worker.name, designate_account_assignment_path(assignment, user_id: worker.id) %></li>
<% end %>
</ul>
</div>
<% end %>
</ul>
</div>
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.
Well, i have a problem, and i was wondering if it could be solved with rails only.
I have setup a view (home.html.erb) vith 3 partials, like this:
<%provide :title, 'Reader'%>
<div class = "row">
<div class = "span4">
<div class = "row">
<%= render 'layouts/add_subscription'%>
</div>
<div class = "row">
<%= render 'layouts/subscription_list'%>
</div>
</div>
<div class = "span8">
<div class = "row">
<%= render 'layouts/view' %>
</div>
</div>
</div>
where subscription_list shows up a list of links pointing to the list action after a redirection, each of them with the id of the subscription:
<ul>
<% current_user.subscriptions.each do |s| %>
<li><%= link_to s.url, "/list?s_id=#{s.id}" %></li>
<% end %>
</ul>
So, each of these links points to the list action in the controller, which tries to fetch the feed list of the subscription just clicked, and update the home view with the list of titles for the selected subscription:
def list
s_id = params[:s_id]
feed = ""
if !s_id.blank?
s = Subscription.find_by(id: s_id)
feed = Feedzirra::Feed.fetch_and_parse(s.url)
#render partial: "layouts/view", :locals => {:f => feed}
end
The problem is that I'm stuck at this point. I've tried to do a redirect_to home_path with feed as a parameter, and even a render (the line before the end of the list method) to see what happened, but nothing updates 'just' the layouts/view partial:
<ul>
<% if defined? feed and !feed.blank? %>
<% f.entries.each do |entry|%>
<li><%= entry.title %></li>
<% end %>
<% end %>
</ul>
So, I was wondering if it's possible to update the partial and see the result after a page reload using only rails methods, or if it can/must be done using javascript, and a clue to how to do this. Thanks in advance.
The goal you want to achieve is to show feed entries in the home.html.erb after clicking a link.
You can do it by pointing your links to the home action instead of list so that rails will automatically render your home.html.erb view and
you have to assign the instance variable #feed so it will be visible in your view.
You can do it like this (refactored a bit):
controller
def home
s_id = params[:s_id]
if s_id.present?
s = Subscription.find_by(id: s_id)
#feed = Feedzirra::Feed.fetch_and_parse(s.url)
end
end
layout/view
<ul>
<% if #feed.present? %>
<% #feed.entries.each do |entry|%>
<li><%= entry.title %></li>
<% end %>
<% end %>
</ul>
I'm not sure what is the path to your action, I assume here that home is the root ("/")
layouts/subscription_list
<ul>
<% current_user.subscriptions.each do |s| %>
<li><%= link_to s.url, "/?s_id=#{s.id}" %></li>
<% end %>
</ul>
I have a method that groups all my book categories together
def self.categories_list
joins(:books).
select('categories.id, categories.name, count(*) AS books_count').
group('categories.id, categories.name').
order('books_count DESC')
end
I can then output them to my view like so
#bookcategories = Category.categories_list
What I want to do then is link to all the books belonging to say 'Computing' by clicking 'Computing' in the view
<% #bookcategories.each do |b| %>
<li><%= link_to b.name, category_path(b.name) %></li>
<% end %>
This should take me to my show action of my category controller
def show
#category = Category.where(:name => params[:name]).first
#categorisedbooks = #category.books #get me all books that have the category name
end
and the view for the show action
<div class="container">
<div class="row ">
<div class="span12">
<% #categorisedbooks.each do |c| %>
<%= image_tag c.avatar.url(:medium), :class=> "allBooksCover" %>
<% end %>
</div>
</div>
</div>
So when I click 'Computing' for example I get
undefined method `books' for nil:NilClass
and the params are being passed as
Parameters:{"id"=>"Computing"}
So, you need in your show action
#category = Category.where(:name => params[:id]).first
# etc
So Im listing out all the members of my site and grouping them by name so that the list will be organized better. So in my view all my members are grouped by the first letter of their member name like:
B
Bakedfish
Beercan Dan
Bigmike33x
C
Cynicalassassin
ect..
Anyway, I also want to paginate this list but I cant add Kaminari's pagination arguments to my controller if Im using order because I get an undefined method error.
so this doesnt work:
#members = Member.all.group_by{|u| u.fullname[0].titleize}.page(params[:page]).per(18)
my view looks like this:
<div class="content">
<%= paginate #members %>
</div>
<% #members.keys.sort.each do |starting_letter| %>
<h3>
<%= link_to starting_letter, {:action => :browse, :controller =>:members, :letter => starting_letter } %>
</h3>
<ol>
<% #members[starting_letter].each do |member| %>
<li>
<% if member.is_artist? %>
<%= link_to member.full_name, member_path(member), :class=>"artist" %>
<% else %>
<%= link_to member.full_name, member_path(member) %>
<% end %>
</li>
<% end %>
</ol>
<% end %>
Here is my error message:
NoMethodError (undefined method `page' for #<Hash:0x007f78d4bf48f8>):
app/controllers/members_controller.rb:10:in `index'
Kaminari adds page method to ActiveRecord::Relation but Member.all.group_by returns hash. That is why you get this exception.
I'd suggest to perform grouping after pagination, e.g.:
#members = Member.order(:full_name).page(params[:page]).per(18).to_a.group_by { |u| u.fullname[0].upcase }
UPDATE
In order to use paginate helper you could assign 2 variables, e.g.:
#paginated_members = Member.order(:full_name).page(params[:page]).per(18)
#members = #paginated_members.to_a.group_by { |u| u.fullname[0].upcase }
And pass #paginated_members to the paginate helper.