I would like to use deep_dup to duplicate the parent and child objects and save as a new record using rails 5. I have been searching to see some example code to implement it on my project but so far i could not find anything.
so far i did this but it does not work.
def copy
#product = Product.find(params[:id])
#newproduct = #product.clone :include => :productlines
success = #newproduct.save
if success && #newproduct.errors.empty?
redirect_to (edit_product_path(#newproduct))
flash[:danger] = "Procut copied"
else
flash[:danger] = "Procut cannot be copied"
end
end
<%= link_to "Clone", copy_product_path(#product), :method => :put %>
the gem deep_cloneable is available but i could not understand the documantation, no idea how to use it.
Can anyone just show me a way to implement this on my project?
Would be really appreciated if someone can help.
It looks like you'll need to use the deep_clone method to include the productlines association (Also make sure it's not supposed to be product_lines).
#new_product = #product.deep_clone include: :productlines
Related
I'm working on a project in rails where I have a database of products, and I'm looking to use forms to manipulate them.
However, I'm having a great deal of difficulty figuring out how to do this.
I tried to use the standard:
<%= form_for(#product) %>
...
<% end %>
to send an entry to my product controller, but that returns a nil/empty field error.
My method to remove products from inventory is below. I strongly suspect this to be highly incorrect, but I have yet to figure out how to get far enough to even receive an error with that:
def ship
#products.where(#products.code = params[:code]).quantity -= 1
end
If there is any way that anybody could guide me in the right direction, I would be highly grateful. I've been trying to figure this out for a while now.
Try like this, let me know what else do you need.
def ship
#product = Product.find_by(code: params[:code]) # or you can use :code => params[:code], but not an equal sign
#product.quantity -= 1
if #product.save
respond_to do |format|
format.html {}
format.json {}
end
end
end
where returns an array or objects.
You after negating the quantity you should save it or update product on the go
You should respond back or else you'll get template missing error, OR you can redirect to some page
I am very new to Rails, I want to be able to insert names into an array attached to my user.
I added an empty array called 'subscribed_tasks' to my 'schema.rb'
And I wondered how I can push data into that array.
My first attempt was:
Having '= link_to "Subscribe", subscribe_task_path, class: "btn btn-default"' in my show.haml and then having this within my route.rb:
resources :tasks do
member do
get :subscribe
end
end
& then adding this to my Tasks_Controller:
def subscribe
#user = current_user
#user.subscribed_tasks << #task.title
redirect_to #task, notice: "Subscribed to "+ #task.title
end
The problems I'm facing are:
How do I pass the task they're subscribing to's parameters to the controller so then the correct data can be pushed into the array. Also, I don't think I'm finding the array correctly.
All in all, what I'm programming is a mess, am I missing something fundamental about Rails and is there an entirely better way to solve this problem?
Hi I am using Rails, vzaar gem to upload the video.
title, description are updating but video file is not updating in vzaar. Any help would be appreciated.
video_controller:
def edit
#course = Course.find(params[:course_id])
#video = #course.videos.find(params[:id])
end
def update
#course = Course.find(params[:course_id])
#video = #course.videos.find(params[:id])
api = Vzaar::Api.new(:application_token => "my token", :login => "myloginname")
api.edit_video(#video.vzaar_id, :path => params[:video][:video].tempfile.path, :title => params[:video][:title])
if #video.update_attributes(:title => params[:video][:title])
redirect_to :back
end
end
title is updating but video with path is not updating. However with same technique i successfully created video in vzaar.
Thanks
It looks like you're trying to replace the actual video content here - is that correct?
If that's the case, it's not the edit_video method that you need to use in this case. As our documentation states, you can only change title, description, private and seo_url that way.
To replace a video, you'll need to use the upload_video method again, but supply a replace_id in the options that marks the video id you want to overwrite. In your case, it'll look something like this:
api.upload_video(path: params[:video][:video].tempfile.path, title: params[:video][:title], replace_id: #video.vzaar_id)
You'd also need to set the other options to match your previous uploads.
I hope this helps, and please let me know if you have any questions, or alternatively contact us on support#vzaar.com. And don't forget to check out the documentation, as that lists all the arguments available for each method.
All the best,
Dan
So, I have something of an odd controller/view setup, editing a Product model object occurs in the listings controller/view. There is a long-winded explanation for why this is, but I digress. However, when I submit the form, I get the error Couldn't find Product without an ID . What gives? Strangely, when I look at the params sent with the request, the ID attribute is assigned to the 'format' key. ?!.
The controller code is very simple. Edit Action:
def edit
#edit = Product.find(params[:id])
end
Update Action:
def update
#edit = Product.find(params[:id])
if #edit.save
redirect_to :url => listings_display_path
end
end
Here is my form_for code:
<% form_for #edit, :url => (listings_update_path(#edit)) do |f| %>
Edit, the trace:
{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"st17LW0S9uENaV8UBcxKUfRH67oo+r3TuFAxiPKMCEc=",
"product"=>{"brand"=>"test_brand",
"productname"=>"test_product",
"category"=>"test_category",
"regprice"=>"4",
"saleprice"=>"2",
"description"=>"description"},
"commit"=>"Submit",
"format"=>"21"}
Edit: routes.rb
resources :product do
resources :promotions
collection do
get "replace"
end
end
#listings
match 'listings/index' => 'listings#index'
match 'listings/display' => 'listings#display'
match 'listings/edit' => 'listings#edit'
match 'listings/update' => 'listings#update'
Edit: create action
def create
#product = Product.new(params[:product])
#product.user = current_user
if #product.save
redirect_to :action => 'index'
end
end
First, for an alternate approach to editing multiple records on a single view, try this railscast: http://railscasts.com/episodes/198-edit-multiple-individually
Second, this is unconventional but your whole approach is unconventional...
You can stick a hidden field in the form with the ID in it. Something like:
<%= f.hidden_field, :product, :id %>
Then check your params hash and the id will be in there. You should be able to access it in the controller using something similar to:
# untested
#edit = Product.find(params[:product][:id])
Off the top of my head I'm not sure how it will be stored in your params hash but it will be there and you'll be able to access it like any other hash attribute.
Good luck!
--EDIT--
Also, regarding your comment about lack of flexibility in Rails -- one thing I've learned is that Rails isn't inflexible, but it is highly optimized for particular conventions. The developers refer to this as being "highly opinionated" software, which means:
It can do just about anything you care to do it any way you want to do it, but...
There's almost always a "preferred" way which is better, faster (harder stronger lol).
You would save yourself tons of time and energy -- and probably have a lot of fun -- grabbing the Beginning Rails 3 book. You could work through it in a weekend, and when you were done you would have a great primer on the "Rails Way" which would hopefully help you go from "I don't get why Rails doesn't do this or that" to "I get how Rails works and how easy it is to do what I want to do by following X pattern". That's what happened for me anyhow.
Again good luck!
Try this
<%= form_for #edit, :url => listings_path(#edit), :html => {:method => :put} do |f| %>
You need to fix the routes that are for a single product instance to have the id:
match 'listings/index' => 'listings#index'
match 'listings/:id/display' => 'listings#display'
match 'listings/:id/edit' => 'listings#edit'
match 'listings/:id/update' => 'listings#update'
I am trying to create a bunch of dynamic helper methods like these:
show_admin_sidebar
show_posts_sidebar
show_users_sidebar
So far I have this in my helper.rb file:
#spits out a partial
def show_sidebar(name, show_sidebar = true)
#content_for_sidebar = render :partial => "partials/#{name}"
#show_sidebar = show_sidebar
end
def show_sidebar?
#show_sidebar
end
In my application layout file I have this: (NB - I'm using HAML):
- if show_sidebar?
= yield(:sidebar)
This allows me to say the following in my views:
- show_sidebar(:foo)
- show_sidebar(:bar)
And this renders the desired partial.
The problem with this is that I can only add one sidebar per page. So, I figure I need to have dynamic methods like: show_admin_sidebar, show_foo_sidebar.
So I have tried to do this:
def show_#{name}_sidebar(show_sidebar = true)
#name = name
#content_for_#{#name}_sidebar = render :partial => "partials/#{#name}"
#show_sidebar = show_sidebar
end
and then in my layout:
- if show_sidebar?
= yield("{#name}_sidebar")
But rails does not like this at all.
I have tried almost everything I can think of in my helper file and nothing works.
The reason I am using helper methods for this is because I want my content div to be 100% page width unless there is a sidebar present in which case the main content goes into a smaller div and the sidebar content goes into it's own..
If I can't get this working, then I can easily fix the problem by just adding the partials manually but I'd like to get my head round this....
Anyone got any experience with this kind of thing?
The entire approach to this was bizarrely overcomplicated, didn't follow Rails conventions at all, nor make the slightest bit of sense, and shame on prior respondents for enabling this approach instead of helping him to simplify. My apologies for being 13 months late with the answer.
Your controller should be deciding if a sidebar is to be shown or not, and setting an instance variable #side_bar_name to either nil or a sidebar name string. Then somewhere in shared view code, probably views/layouts/application.html.erb, you would have something as simple as this:
<% if #side_bar_name %>
<%= render :partial => "partials/#{#side_bar_name}" %>
<% end %>
Or better yet:
<%= render(:partial => "partials/#{#side_bar_name}") if #side_bar_name %>
If you want to use a helper (which is not a bad idea for keeping your code DRY and readable) it would basically be the same code, just moved into the helper.
<%= side_bar_helper %>
def side_bar_helper
render(:partial => "partials/#{#side_bar_name}") if #side_bar_name
end
What the controller does is up to you. It would probably do something like this:
if session[:show_side_bar]
# maybe use cookies instead of session, or store user preference in a database
#side_bar_name = session[:side_bar_name]
end
Here is a solution for you, however I wouldn't suggest too much metaprogramming:
#Add the following snippet to the proper helper module:
['admin','user','whatever'].each do |name|
class_eval{
"def show_#{name}_sidebar(show_sidebar = true)
#name = #{name}
#content_for_#{#name}_sidebar = render :partial => 'partials/#{#name}'
#show_sidebar = show_sidebar
end"
}
end
def show_#{name}_sidebar(show_sidebar = true)
That doesn't look like valid Ruby to me. Are you parsing and evaling this yourself or just throwing that right in the file and expecting it to work?