I have a model, called line_items. It contains price field. When user enters price, it can be foodio_price or delivery_price. And price field has lot of such values.
I want to put check on this. Here is my condition:
All the prices in price field should be foodio_price or delivery_price. If not, give error and if yes, give whether it is foodio_price or delivery_price.
Can anybody help in implementing it?
I did something quite dirty which is not working:
#line_items.each do |i|
if i.price == i.product.foodio_price
#line_items.each do |i|
if i.price == i.product.delivery_price
render :action => "cart"
end
end
else
#line_items.each do |i|
if i.price == i.product.foodio_price
render :action => "cart"
end
end
end
end
It gives error of too many render or redirect calls
The clue's in the error message -- you can only render or redirect once per action.
Try adding a return straight after each call to render.
I'm not clear about your logic, however you cannot call more than one render or redirect per action and as a convention you should call only one redirect or render at the end of the action.
However this might give you an idea about your logic:
#line_items.each do |i|
product = i.product
if ([product.foodio_price, product.delivery_price].include(i.price))
#once of your prices
else
#neither of your prices
end
end
Related
I want to be able to update a record via params. Something like this:
http://domain.com/api/v1/notes/2190/notify?message=test
But it just returns a page not found. Pretty standard routes going on:
resources :notes, only: [:show] do
post 'notify'
end
My notify method looks like this:
def notify
#note = Note.find(params[:id])
if params[:message]
render text: #note.update_attributes(message: params[:message])
end
end
Do I need to do anything else to permit this functionality? Any advice at all? I can't figure it out. Cheers.
The routes should be something like:
resources :notes, only: :show do
member do
get 'notify'
end
end
In products_controller.rb
# GET /search/'brand'
def brand
#product = Product.find_all_by_brand(params[:brand])
respond_to do |format|
format.html # brand.html.erb
end
end
In routes.rb
match '/search/:brand' => 'products#brand'
If I try accessing localhost:3000/search/Apple I get the following error Couldn't find Product with id=Apple
Is there anything that I'm missing? Are there any other files that I should handle?
Update
Now I'm getting undefined method 'size' for nil:NilClass and I'm not even sure what I changed.
The query executed by rails is select "products".* FROM "products" WHERE "products"."brand" = 'Apple' ORDER BY last_seen DESC and they seem to return the correct products.
Application Trace
app/views/products/_product.html.erb:1:in
_app_views_products__product_html_erb___2255278_29707176'
app/views/products/brand.html.erb:1:in
_app_views_products_brand_html_erb___464952485_38589588'
app/controllers/products_controller.rb:52:in `brand'
The comments in your controller indicate that you might want to try /search/brand/Apple.
Found the error, the erb page was receiving product instead of products. Typing error.
There are a couple of places where I could do what I need, but I'm not sure where the best place is in line with good practices.
I have an Orders controller, and after a successful order is created I want to create a subscription (but only if the order is a success), and a referral (but only if the order is associated with one).
Now the obvious choice is to use after_create on the Order model... but... how can I get session data into that? (The referral ids, friend ids and voucher ids are only in the session as there's no need to store them in the Order db).
So should I just create the Subscription and Referral objects in the create action (how I have it at the mo) or is there a better way?
Here's my create action:
(#order.purchase only returns true if the payment was successful)
def create
if #order.save
if #order.purchase
Subscription.create(:order_id => #order.id, :product_id => #order.product_id)
if #order.voucher
Referral.create(:user_id => session[:friend_id], :order_id => #order.id,
:voucher_amount => #voucher_value)
end
render :action => "success"
else
render :action => "failure"
end
else
render :action => 'new'
end
end
Any help would be appreciated - I really would like to do this properly so I hope no one minds me asking what is probably a simple question.
I recently had a similar question, please take a look, i think that a simple virtual attribute in a callback will do it for you as well.
Fetch current user in after_create filter
use of callbacks will make your life easy, you need to use after_save
do all your stuff in after_save callback of order model. see rails api doc for callback here
Edit: If the session variable is not available with model, you can have a post_save method to deal with all logic which also accepts all require params like
like
class Order < ActiveRecord::Base
def post_save require_attr
#create subscriptions
# create referral
end
end
I have a Rails3 app that has Workflows, and they have many WorkAssignments. WorkAssignments have a field, work_sent_date, the date work was sent to the person. On the Workflow edit screen I display a work sent date field, but Workflow does not have an attribute work_sent_date. If any work assignments have a date, I display the most recent one and it can't be edited. If all are blank, I display a text box that is editable and in WorkflowController#update, if that date is filled it, the work assignments' work_sent_date field get that date.
It works when I test it manually. I suppose I could just create an attribute for it, but I'm trying to be slick and not have redundant data.
I'm trying to write a test for this. First I assert that the WorkAssignment#work_sent_date is blank for all work assignments. Then I try a "post :update" and I can't figure out how to pass in the work_sent_date value, which is a form field but not an attribute. What I want to do is something like.
test "setting work_sent_date in wf sets it in wa" do
#workflow.work_assignments.each do |wa|
assert wa.work_sent_date.blank?
end
get :edit, :id => #workflow.id
assert_response :success
post :update, :workflow => #workflow.attributes, :parameters => {'work_sent_date' => Date.today.to_s}
#workflow.work_assignments.each do |wa|
assert_equal(wa.work_sent_date, Date.today)
end
end
But that parameters field doesn't work. There's no error, but I keep getting failures because wa.work_sent_date is still nil, so it's not getting passed in correctly. How do I pass today's date in as an extra parameter?
(Or maybe there's a better way to do the whole thing, which I would gladly consider.)
I know this is complicated. I hope I explained it well. Any suggestions would be appreciated. I've googled to death and can't find anything.
Found my problem. Syntax way wrong. Here's what it should be. This works.
put :update, :id => #workflow.id, :workflow => #workflow.attributes, :work_sent_date => Date.today.to_s
You can also refactor out the create and edit as follows:
protected
def edit_workflow(workflow, options = {})
post :update, :id => workflow.id, :workflow => workflow.attributes.merge(options)
end
def create_workflow(options = {})
post :create, :workflow => {}.merge(options)
end
end
I am trying to figure out the best way to build an if else if statement in the controller around a rails specific referrer. Is there a way to pull the last rails path and use it in the below statement? I think I am close but totally stumped...
This is an update action that will be hit from one form at multiple locations on the site.
I am looking to replace "form_path"
def update
#object = Milestone.find(params[:id])
if #milestone.update_attributes(params[:milestone])
if request.referer == form_path
redirect_to root_path
else
redirect_to object2_path
end
else
....
end
end
Is form_path a variable you're defining somewhere else in the controller? Outside of understanding that, it looks like it should work.
Instead of messing with referer, you could place a hidden_field in the form based on where it's coming from, and pull that out of the params hash.
Something like:
hidden_field_tag :location, controller_name
Then in the controller:
if params[:location] == yadda yadda