Rendering a rails partial inside of another partial - ruby-on-rails

I have a page listing many products, at taxons#show. Inside of taxons#show I'm rendering the partial _products.html.erb to display the products, images, variants, etc. By default, when you click an individual product on taxons#show rails redirects you to the products#show page where the partial _cart_form.html.erb is rendered which displays add to cart options.
However, I'm trying to render _cart_form.html.erb inside a lightbox in _products.html.erb, which is inside of taxons#show. My problem is that _products.html.erb is using
<% products.each do |product| %>
to display each individual product. And _cart_form.html.erb is using #product to display all of its product info. If I keep it this way I get a NoMethod error for nilClass because #product isn't defined.
Then I tried:
<% #product = product %>
<%= render 'spree/shared/cart_form' %>
But because this is above the code that outputs all of the products on taxons#show it changes every product inside _product.html.erb to the same product, the first one listed.
How can I render _cart_form.html.erb inside of a lightbox for each individual product?
Here's taxons_controller.rb:
def show
#taxon = Taxon.find_by_permalink(params[:id])
return unless #taxon
#taxon_id = params[:id].split('/').first
if #taxon_id
instance_variable_set "#enable_#{#taxon_id}", true #big lettered taxonomy heading
end
#product_type = params[:id].split('/').last
#featured = #taxon_id + '/' + #product_type #featured image
#searcher = Spree::Config.searcher_class.new(params.merge(:taxon => #taxon.id))
#searcher.current_user = try_spree_current_user
#searcher.current_currency = current_currency
#products = #searcher.retrieve_products
#related_products = #taxon.products.offset(rand(Spree::Product.count - 7)).limit(7)
respond_with(#taxon)
And products_controller.rb:
def show
return unless #product
#variants = #product.variants_including_master.active(current_currency).includes([:option_values, :images])
#product_properties = #product.product_properties.includes(:property)
referer = request.env['HTTP_REFERER']
if referer
begin
referer_path = URI.parse(request.env['HTTP_REFERER']).path
# Fix for #2249
rescue URI::InvalidURIError
# Do nothing
else
if referer_path && referer_path.match(/\/t\/(.*)/)
#taxon = Taxon.find_by_permalink($1)
end
end
end
respond_with(#product)
end

Related

Map name of model object to a pg_search query param in Rails 5.1

I have an album model, that has one 'cover_image' and has_many 'images'. I also have a product model. I am using pg_search to filter my products.
Independently, they both work flawlessly. What I would like to do is show an albums cover_image based on the pg_search filter param.
For example: If I had a filter param called "limestone", I would create an album called "limestone" and when a user filters the page by limestone, they would get the product results along with the matching cover_image.
product_controller - this works for filtering
def index
#products = if params[:query]
Product.search_for(params[:query])
else
Product.order(:name)
end
end
product_controller - this breaks the page
I tried this in an attempt to keep it simple and filter the image in the model
def index
#products = if params[:query]
Product.search_for(params[:query])
*#albums = Album.where(name:(params[:query]))*
else
Product.order(:name)
end
end
products/index.html.erb Then I would just call the album as normal.
...
<% #albums.each do |a| %>
<%= image_tag("#{a.cover_image_url(:original)}") %>
<% end %>
...
The problem is that you're assigning #albums to #products. This is in effect what you're doing:
#products = #albums = Album.where(name: (params[:query]))
because the if statement is returning #albums. So this should work (assuming that the rest of your logic is correct):
def index
#products = if params[:query]
#albums = Album.where(name: params[:query])
Product.search_for(params[:query])
else
Product.order(:name)
end
end
However, I would not assign #albums where you are doing so right now. I think this is clearer thus slightly better:
def index
if params[:query]
#products = Product.search_for(params[:query])
#albums = Album.where(name: params[:query])
else
#products = Product.order(:name)
#albums = []
end
end

How to Render a Enquery form in a product show page

I Have a product's show page which displays the information about the product. I also have an enquery form on the same show page, so the user can send an enquery regarding the product.The enquery data has to be saved into the Enquery model with a corresponding EnqueresController which should have index and show actions.
How can this be done in Rails?
Any help is highly appreciated. Thanks in Advance!
#product = Product.find(params[:id])
#enquery = Enquery.where("product_id = ?",#product.id).present?
In the app/controllers/products_controller.rb
class ProductsController < ApplicationController
// initialize your enquiry model object here
// since you are showing the form on show page
def show
#products = Products.all
#enquiry = Enquiry.new
end
end
after that in the show view at show.html.erb
<%= form_for #enquiry do %>
<%= text_field :modelname, :attribute_name, options %>
....
....
<% end %>

Rails, getting information from html

In my rails app, I have product and order models. Lets say the products controller look like this:
def index
#products = Product.all
#order = Order.new
end
I have listed all products in the index view as divs. I would like to assign a product's id to the order (#order.product_id = product.id) when I click on its div.
= #products.each do |product|
.product
= product.name
= product.price
Any ideas how to do this :? Thank you!
You need to trigger another request that includes the product ID, and land on a new action that assigns the ID to #order.product_id. In this case, it makes no sense to have #order = Order.new in your products#index action; instead you probably want a nested resource for orders within products, and a new controller for handling orders for a product.
config/routes.rb
resources :products do
resources :orders
end
app/controllers/products_controller
def index
#products = Product.all
end
Now, the products#index view can link to the nested route for a new order within a product. This will product a URL like /products/123/orders/new:
app/views/products/index.html.shaml
= #products.each do |product|
.product
= link_to new_product_order_path(product) do
= product.name
= product.price
Finally, you can render the new Order form using the product specified in the route:
app/controllers/orders_controller
def new
#product = Product.find(params[:product_id])
#order = #product.orders.new
end

Loop through two object arrays, sort by date created

I'm trying to sort out how to loop through two object arrays and display them in mixed order in a view – by the date they were created.
Here's my current controller code, that only displays Posts based on the category you're in, or, based on a search query:
def browse
#user = current_user
if params[:category]
#category = Category.find(params[:category])
#posts = #category.posts.page(params[:page])
else
#posts = Post.search(params)
end
end
In the view, I just loop through and output these like so:
- if #posts
- #posts.each do |post|
= post.name
= post.content
What I'd like to do, is instead of referencing posts via the instance variable #posts... I'd like to create a new variable (ie: #everything) – that pulls objects from the Post class and the Comment class, pops them into the same array, and allows me to loop through and output each respectively in my view, like this:
Ideal controller:
def browse
#user = current_user
if params[:category]
#category = Category.find(params[:category])
#everything = #category.everything(params[:page]) # ... combination of comments and posts
else
#everything = Everything.search(params)
end
end
Ideal view:
- if #everything
- #everything.each do |e|
- if e.type == 'post'
= e.name
= e.content
- else
= e.comment
Any help/guidance is appreciated. I'm just not sure how to approach this.
You would do this type of thing (to get you started)
def browse
#user = current_user
#everything = #category.posts | #category.comments
end
In the view
%ul= render #everything
Make sure there is a views/comments/_comment.html.haml and a views/posts/_post.html.haml files.
Or you could render a specific partial and handle any differences in there
%ul= render :partial => shared/everything_item, :collection => #everthing

Paginate child models Kaminari on rails 3.1

I have 2 models images and categories.
The relations are:
- a image belongs to one category.
- a category has many images.
On the index.html.erb view from categories object, I want paginate 20 images per page for all categories.
I mean, I want paginate all images from all categories with 20 images per page.
in my index action on categories_controller.rb method I have:
def index
#categories = Category.all
#categories.each do |category|
#images = Kaminari.paginate_array(category.images).page(1).per(1)
end
respond_to do |format|
format.html # index.html.erb
format.json { render json: #categories }
end
end
on index.html.erb I have:
<% #images.each do |image|%>
code for each image here
<% end %>
<% paginate #images %>
But this for me it does not works. I can not see anything image showed.
how I can implement this functionality? and fix this problem? Thank you.
#categories.each do |category|
#images = Kaminari.paginate_array(category.images).page(1).per(1)
end
In this loop, you're overriding #images each time, so obviously, you wont get what you expect ;)
I think that what you wanna do is:
#images = Image.where("category_id IS NOT NULL").page(params[:page]).per(20)
The .where("category_id IS NOT NULL") is not necessary if images have to belong to a category.

Resources