Reputation: 307
this is the main idea of my website
The user number 1 see a picture he likes(uploaded by user number 2) if user number 1 has enough points(the specific number selected by user number 2) he clicks on download link,and gets redirected to the download page...and the user number 2 who owns the picture gets his points. The way user number1,gets his points back is to upload a picture himself,and other users have to download it,so he again has points to download pictures from other user.
The model and their controllers to work here is Picture.rb and User.rb This is what i tried
1.Add to user model , “points" column,make it an integer,it will show the number of points the user has
2.Add to picture model “points_needed” column,should be integer as well,show the amount of points needed to download the picture
3.Add to picture model "picturelink" column,the users will insert into that field,when uploading a picture the url to their picture,so the users who download can be redirected to that download URL.(like getting to the final page,to the product,after clicking buy now,as an example)
When creating a picture,in picture views, new.html.erb
i put
<%= f.input :picturelink, :placeholder => "Enter the link(URL) to the files you want to share" %>
and
<%= f.number_field :pointsneeded %> # let them select how many points they
will charge
and to show it in show.html.erb,also in picture model i put
<%= @picture.picturelink %> #shows the Url of the picture download page(it will be hidden later)
and
<%= @picture.pointsneeded %> #show the points needed to get this picture
and it shows everything perfectly
Question: How can I make,when user number 1 wants to download a picture owned by user number 2,if user nr.1 clicks "get this picture button" he gets redirected to the download page,and the points are transferred to user number 2 the picture's owner.
Edit after trying the given solutions: after clicking on
<%= link_to "Get this picture", download_picture_path(@picture) %>
I keep getting
undefined method `pointsneeded' for #<Picture::ActiveRecord_Relation:0x007f8e20193ba0>
This is what i used in my Picture Controller
def downloadpage
ActiveRecord::Base.transaction do
current_user.points -= @picture.pointsneeded #this line gives error,and the next
@picture.user.points += @picture.pointsneeded
current_user.save
@picture.user.save
redirect_to @picture.picturelink #redirect to the final picture
end
end
Routes
get '/downloadpage/:picture_id' => "pictures#downloadpage", as: :download_picture
**
Final solution:
** change the routes to(note i use :id,not :picture_id)
get '/downloadpage/:id' => "pictures#downloadpage", as: :download_picture
in controller add(the show,edit...are not important,they are just for my app needed),i added :download page
before_action :find_picture, only: [:show, :edit, :destroy, :update, :upvote, :downloadpage]
And that's it,it worked,thanks to @Mario,for more details on how i solved this question,look into our chat,link located into @Mario and me sub-comments.
Upvotes: 2
Views: 82
Reputation: 1359
In order to control the entire experience you would send the buying user to a download
action in your PicturesController.
Inside this action you'd use a transaction to remove points from the 'buying' user and give them to the 'selling' user like so:
ActiveRecord::Base.transaction do
current_user.points -= @picture.pointsneeded
@picture.owner.points += @picture.pointsneeded
current_user.save
@picture.owner.save
end
replacing current_user
and @picture.owner
to whatever you call the buying and selling users, respectively. Using a transaction ensures that BOTH the removal and addition of points happen, or otherwise neither will happen. Imagine if a user lost points while no one gained! Imagine if this was money! That'd be catastrophic. You use transactions when you want to ensure everything is saved or rolled back if an error occurs.
and then either use redirect_to
to send them to the @picture.picturelink
directly OR, if you want to hide the direct link from the buying user (which I think is a good idea to protect the 'seller') you could use something like:
require 'open-uri'
url = @picture.picturelink
data = open(url).read
send_data data, :disposition => 'attachment', :filename=> "#{@picture.name}.#{@picture.picturelink.split('.').last}"
Upvotes: 3
Reputation: 925
Marios answer is great (never knew about transactions). The only thing I can add if you don't know, is you need to make a new route in routes.rb
to your download action in your PicturesController
in order for the "get this picture button" to work.
Upvotes: 2