Mike McCallen
Mike McCallen

Reputation: 307

Points exchange between users Rails 4

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

Answers (2)

Mario
Mario

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

oobie11
oobie11

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

Related Questions