Ruby on rails verfijning pg_search_scope v2.2

stemmen
46

Ik ben erg nieuw voor Ruby on Rails en ik help uitzoeken hoe een bestaande db vraag wijziging nodig. Ik ben met behulp van oude versies, die ik niet kan werken: Ruby 2.2.3p173 en Rails 4.0.2.

Ik wil de bestaande query resultaten te filteren om records die geen video hebben te verwijderen. Het model hiërarchie ik denk is: artiest, AlbumGroup, Album, Baan, Video.

Voor alle duidelijkheid: ik wil kunstenaars met ten minste 1 video, uit het model vereniging artiesten-> AlbumGroup-> albums-> tracks-> video's (niet artiest-> video's).

De bestaande query wordt opgenomen in model Artist:

require_dependency tagging
require_dependency similar
class Artist < ActiveRecord::Base
  has_many :images, dependent: :destroy
  has_many :taggings, dependent: :destroy
  has_many :artforms, through: :taggings
  has_many :similars, foreign_key: similar_id, dependent: :destroy
  has_many :similar_artists, through: :similars, source: :similar_to
  has_many :reverse_similars, foreign_key: similar_to_id, class_name: Similar, dependent: :destroy
  has_many :similar_to_artists, through: :reverse_similars, source: :similar
  has_many :memberships, foreign_key: member_id, dependent: :destroy
  has_many :groups, through: :memberships, source: :membership
  has_many :group_members, foreign_key: membership_id, class_name: Membership, dependent: :destroy
  has_many :members, through: :group_members, source: :member
  has_many :users, through: :followed_artists
  has_many :videos, dependent: :destroy
  has_many :audios, dependent: :destroy
  has_many :metrics, through: :audios
  has_many :releases, foreign_key: 'artist_id', class_name: AlbumGroup
  has_many :albums
  has_many :collaborations
  has_many :album_groups, through: :collaborations
  mount_uploader :mugshot, MugshotUploader
  include PgSearch
  pg_search_scope :for_name,
      against: :name,
      using: { tsearch: {threshold: '1', dictionary: 'simple', tsvector_column: 'tsv_name', prefix: true, normalization: 2}},
      ranked_by: (artists.popularity / 50 * :tsearch) + :tsearch
end

Ik wil iets als het volgende te filteren uit de verslagen die geen video hebben toe te voegen: (aan de vraag):

if: artist.releases.albums.tracks.videos.count > 1

Of het Artist model misschien ?:

scope :valid, -> {where(video_count > 1)}

De andere code voor de verschillende modellen is hieronder:

class AlbumGroup < ActiveRecord::Base
  belongs_to :artist
  has_many :collaborations
  has_many :artists, through: :collaborations
  has_many :albums
  has_many :taggings, dependent: :destroy
  has_many :artforms, through: :taggings
  mount_uploader :artwork, MugshotUploader
  def as_json options={}
    {
      id: id,
      title: title
    }
  end
end

class Album < ActiveRecord::Base
  belongs_to :album_group
  belongs_to :artist
  has_many :tracks
end

class Track < ActiveRecord::Base
  has_many :playlist_tracks, dependent: :destroy
  has_many :playlists, through: :playlist_tracks
  belongs_to :audio
  belongs_to :video
  has_many :videos
  has_many :audios
  has_many :taggings, dependent: :destroy
  has_many :artforms, through: :taggings
  belongs_to :album
  belongs_to :artist
  default_scope order: position ASC
  after_save :cache_columns

  def cache_columns
    if image_url.nil?
      img = album.album_group.artwork_url(:tiny)
      unless img.nil?
        update_column(:image_url,img)
      end
    end
    if artist_name.nil?
      if artist_id
        name = Artist.find(artist_id).name
        update_column(:artist_name,name)
      end
    end
    if album_name.nil?
      if album_id
        title = Album.find(album_id).title
        update_column(:album_name,title)
      end
    end
  end
end

class Video < ActiveRecord::Base
  belongs_to :artist
  belongs_to :event
  belongs_to :track
  has_many :tracks
  has_many :playlists, through: :tracks, order: tracks.position ASC
  scope :valid, -> {where(flag_count < 2).order(score DESC) }
  scope :flagged, -> {where(flag_count > ?, 1) }
#   validates :url, uniqueness: {scope: :artist_id}
end
De vraag is gesteld op 07/11/2017 om 14:20
user
In andere talen...                            


2 antwoorden

stemmen
0

ActiveRecord's has_manyen belongs_tomethoden geven u de mogelijkheid om scopes direct in te nemen over de vereniging. Op deze manier kunt u de SQL die wordt gegenereerd wanneer u de vereniging aan te passen.

laten we zeggen dat je wilde een werkingsgebied op het Artist model waarin alle kunstenaars die hebben nul video's terug te definiëren. In Rails 5, aan alle artiesten die geen video's vinden, kunt u gebruik maken vanleft_outer_joins

class Artist < ActiveRecord::Base
  has_many :videos
  scope :with_zero_videos, -> { left_outer_joins(:videos).where(videos: {id: nil}) }
end

Een andere goede oplossing is het gebruik includesals volgt:

Artist.includes(:videos).where(videos: { videos_id: nil })

U kunt degene die je het liefst kiezen!

Hoop dat het hielp.

antwoordde op 07/11/2017 om 15:12
bron van user

stemmen
0

Thanks Gabriel, heb ik een ruwe SQL-query om artists_controller.rb, die net als kijkt toegevoegd:

  def index
    #artists = Artist.for_name(params[:name])
    artists = Artist.find_by_sql ["SELECT artists.*, ((artists.popularity / 50 * (ts_rank((artists.tsv_name), (to_tsquery('simple', ''' ' || ? || ' ''' || ':*')), 2))) + (ts_rank((artists.tsv_name), (to_tsquery('simple', ''' ' || ? || ' ''' || ':*')), 2))) AS pg_search_rank FROM artists " +
      "JOIN album_groups on (artists.id = album_groups.artist_id) " +
      "JOIN tracks on (tracks.album_group_id = album_groups.id) " +
      "JOIN videos on (videos.track_id = tracks.id) " +
      "WHERE (((artists.tsv_name) @@ (to_tsquery('simple', ''' ' || ? || ' ''' || ':*')))) " +
      "GROUP BY artists.id " +
      "ORDER BY pg_search_rank DESC, artists.id ASC", params[:name], params[:name], params[:name]]
    render json: artists, each_serializer: SimpleArtistSerializer
  end
antwoordde op 08/11/2017 om 13:42
bron van user

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more