简体   繁体   中英

Rails 4, how to do a controller specific action in create.js.erb

I am trying to re-render a partial, based on which page it happens. I can't seem to get it to work, it always goes to my else.

create.js.erb

$(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text') %>")
<% if controller_name == "homes" && action_name == "pits" %>
    <% product_type = ProductType.where(name: 'Fosa') %>
    <% @products = Product.where(product_type: product_type) %>
<% elsif controller_name == "homes" && action_name == "coffin" %>
    <% product_type = ProductType.where(name: 'Féretro') %>
    <% @products = Product.where(product_type: product_type) %>
<% else %>
    <% actions = ProductType.where("name not in ('Fosa','Féretro')").uniq.pluck(:id) %>
    <% actions = -1 if actions.length == 0 %>
    <% product_type = ProductType.where('id IN (?)',actions) %>
    <% @products = Product.where(product_type: product_type) %>
<% end %>
<% @invoice_product = current_invoice.invoice_products.new %>
$(".list_products").html("<%= escape_javascript(render 'homes/list_products', products: @products, invoice_product: @invoice_product) %>")

I finally got it:

It was always calling the same controller, the create. I needed to create an instance variable in said controller, to access it through this file. This is my final code:

$(".cart-text").html("<%= escape_javascript(render 'layouts/cart_text') %>")
<% if @product_type_name == "Fosa" %>
    <% product_type = ProductType.where(name: 'Fosa') %>
    <% @products = Product.where(product_type: product_type) %>
<% elsif @product_type_name == "Féretro" %>
    <% product_type = ProductType.where(name: 'Féretro') %>
    <% @products = Product.where(product_type: product_type) %>
<% else %>
    <% actions = ProductType.where("name not in ('Fosa','Féretro')").uniq.pluck(:id) %>
    <% actions = -1 if actions.length == 0 %>
    <% product_type = ProductType.where('id IN (?)',actions) %>
    <% @products = Product.where(product_type: product_type) %>
<% end %>
<% @invoice_product = current_invoice.invoice_products.new %>
$(".list_products").html("<%= escape_javascript(render 'homes/list_products', products: @products, invoice_product: @invoice_product) %>")

Most of the queries that you have here within the erb conditional don't belong in the view and it's not necessary for them to be there. Why do you have conditionals to "do something" for each different product_type_name?

Look at what is repeated in every conditional. There is no reason to repeat the query for product_type in every conditional, likewise for the @products query. There is no reason to have duplicates of the same two queries in three places, and really the conditionals are just not necessary to begin with. Very sloppy. The product_type query is basically added weight and performance penalty for no good reason. If there is a way to have product_type_id instead of product_type_name, you can just go ahead and delete the product_type query all together. If you really only have access to @product_type_name, then it is no big deal you still don't need a product_type query. Think about the duplication, think about why you are doing the "operations" you are doing, and then think about what you are trying to do.

Notice with the product_type query that is duplicated repeatedly, the only thing that changes is the name. You do not need conditional for each possible different product_type_name. Even if there was a reason to query ProductType.where(name: @product_type_name),there still is no reason to duplicate that query and certainly not three times. Think about what is done in each conditional and what it is you are querying for!

Break it down:

Using @product_type_name you are querying the product_types table, so you can get back a product_type. The variable that is important to the @products query is product_type. The only thing that matters is that you get the product_type and @product_type_name is being used only to get product_type. Here's the thing. There is no reason to duplicate the query in three places. In fact, you don't even need the query once you can get rid of it all together.

How can this be?

Think about the duplication and the conditionals, what are they used for why are they there? You don't need more than one query, and what are you using the conditionals for? To get the @products you need only one query. If the "product_type" column isn't a foreign key already, it should be. You can use @product_type_name and not change much. All you need is one query with joins, that is dynamic. That's it. No unnecessary duplicated conditionals, and duplicate queries within conditionals. You can eliminate all the conditionals, the query can do what your conditionals because it is dynamic. No need for conditions based on name, completely unnecessary. The query should be able to get @products, and do so no matter what the @product_type_name is. The query will look something like this:

@products = Product.joins("INNER JOIN product_types ON product_types.id = products.product_type_id").where(product_types: {name: @product_type_name})

Get the above joins query to work and it eliminates all of your conditional code and duplicated queries. Spend some time thinking about joins group and group_by. Get the idea of putting the same two queries in several conditionals, in the view out of your mind. Figure out why you thought that was a good way to do this, and purge it from your mind! Also, consider plucking only the attributes you will use for the @products unless you are unconcerned with performance.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM