Dinukaperera
Dinukaperera

Reputation: 97

How to give an instance variable access to an 'id' in rails?

I have a "userinfos_controller" where user stores their information. They also can upload a video to their profile. I am showing this video under the show method in the userinfos_controller as shown below. I want the '@myvideo" to get the video associated with the user. When a user deletes their video and re-upload, the video_id changes. So I can't call that video using the video_id. Is there a way to call Video.userinfo.last? I don't want to call Video.last, because it'll give me the last video uploaded across all users, not just the last video uploaded by that particular user. You can also see in my rails console, the video has a user_id, userinfo_id and a video_id. So right now, under my show method, when I do:

def show
    @myvideo = Video.find(params[:userinfo_id])
end

It looks for Video_id that is equal to userinfo_id, while I want it to look for the last video uploaded by that particular user/userinfo.

My id relationships(please right click and open in new tab to see more clearly):enter image description here

My userinfos controller:

class UserinfosController < ApplicationController
    before_action :find_userinfo, only: [:show, :edit, :update, :destroy]
    before_action :authenticate_user!

    def index
      @userinfors = Userinfo.all
      @myvideo = Video.all
    end

    def show
        @myvideo = Video.find(params[:userinfo_id])
    end

    def new
        @userinformation = current_user.userinfos.build
    end

    def create
        @userinformation = current_user.userinfos.build(userinfo_params)
        if @userinformation.save
          redirect_to root_path
        else
          render 'new'
        end
    end

    def edit
    end

    def update
    end

    def destroy
        @userinformation.destroy
        redirect_to userinfo_path
    end

    private
        def userinfo_params
            params.require(:userinfo).permit(:name, :email, :college, :gpa, :major)
        end

        def find_userinfo
            @userinformation = Userinfo.find(params[:id])
        end
end

Show video view:

<div>
    <%= video_tag @myvideo.introvideo_url.to_s, :size => "480x320", :controls =>true %>
</div>

Video model:

class Video < ActiveRecord::Base
    belongs_to :userinfo
    belongs_to :user
    mount_uploader :introvideo, VideoUploader 
end

Userinfo model:

class Userinfo < ActiveRecord::Base
    belongs_to :user
    has_many :videos
end

User model:

class User < ActiveRecord::Base
  has_many :vidoes
  has_many :userinfos
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable
end

My migrations that show all the id's added: enter image description here

My routes:enter image description here

Upvotes: 1

Views: 702

Answers (3)

max
max

Reputation: 101811

Either create a direct association between User and Video - or make it indirect through a join model. Don't do both.

Direct 1-n:

class User < ApplicationRecord
  has_many :videos
  has_many :user_infos
  # ...
end

class Video < ApplicationRecord
  belongs_to :user
  # ...
end

class UserInfo < ApplicationRecord
  belongs_to :user
  has_many :videos, through: :user
end

Indirect 1-n:

class User < ApplicationRecord
  has_many :user_infos
  has_many :videos, through: :user_infos
  # ...
end

class UserInfo < ApplicationRecord
  belongs_to :user
  has_many :videos
end

class Video < ApplicationRecord
  belongs_to :user_info
  has_one :user, through: :user_info
  # ...
end

Both will let you do:

@user.videos.last
@user_info.videos.last

def show
  @my_video =  @user_info.videos.order(created_at: :desc).last
end

Upvotes: 1

Simon Polak
Simon Polak

Reputation: 1989

Not sure if I understood you correctly, but I think you want to access the Video that your user previously uploaded, after it uploaded the new one. Assuming you have a has_many :videos relationship set up on the User model, you can do this:

@user.videos.order(created_at: :desc).second

Or if you don't have the user instance and just have user_id.

Video.where(userinfo_id: params[:userinfo_id]).order(created_at: :desc).second

Hope this helps.

EDIT:

Or maybe you just want to access the latest users video. Again, I don't know how you set up your relations. I am assuming user can have many videos.

Video.where(userinfo_id: params[:userinfo_id]).order(created_at: :desc).first

Or shorter

Video.where(userinfo_id: params[:userinfo_id]).last

Upvotes: 1

Sebasti&#225;n Palma
Sebasti&#225;n Palma

Reputation: 33420

Try with ActiveRecord#last:

def show
  @myvideo = Video.where('userinfo_id = ?', params[:userinfo_id]).last
end

That will give you the videos uploaded to userinfo with id equal to params[:userinfo_id] taking the last record.

Upvotes: 1

Related Questions