0

I'm creating an app in Ruby on Rails where users can listen to 2 different types of songs. I want to track each song(and type) that a user listens to. User can listen to a user_song or a master_song. My first thought was to use polymorphic associations.

Firstly, my user model looks like this:

class User < ActiveRecord::Base 
has_many :song_listens, :foreign_key => "user_id"

and then. I declare polymorphic this way:

class SongListen < ActiveRecord::Base
belongs_to :listenable, :polymorphic => true
belongs_to :user

class UserSong < ActiveRecord::Base
has_many :song_listens, :as => :listenable, :class_name => "SongListen"

class MasterSong < ActiveRecord::Base
has_many :song_listens, :as => :listenable, :class_name => "SongListen"

My SongListens migration:

class CreateSongListens < ActiveRecord::Migration
  def change
    create_table :song_listens do |t|
      t.integer :user_id
      t.references :listenable, :polymorphic => true

      t.timestamps
    end
  end
end

The problem comes in when I try save a user's song listen in the polymorphic table. I get nil for type and id. See -->:

[["created_at", Mon, 07 May 2012 18:25:34 UTC +00:00], ["listenable_id", nil],["listenable_type", nil], ["updated_at", Mon, 07 May 2012 18:25:34 UTC +00:00], ["user_id", 1]]

As you can see, the user_id is being set.

My SongListensController:

def create
@song_listen = current_user.song_listens.build(params[:listenable_id => :user_song_id])
@song_listen.save
end

def create_ms_listen
@song_listen = current_user.song_listens.build(params[:listenable_id => :master_song_id])
@song_listen.save
end

My view:

<% @user_songs.each do |user_song| %>
<td><%= link_to 'Play Song', user_song.song.url, class: :play, remote: :true %></td>
<% end %>

<% @master_songs.each do |master_song| %>
<td><%= link_to 'Play Song', master_song.m_song.url, class: :play, remote: :true %></td>
<% end %>

I think this explains the majority of my problem, but for fun, I'm using ajax to create song listen through a music player which sends data through route to SongListen create action:

$('a.play').click(function(e) {
    e.preventDefault();
    $("#jquery_jplayer_1")
        .jPlayer("setMedia", {mp3: this.href })
        .jPlayer("play");
$.ajax({
  url: '/create_ms_listen.json',
  data: { "master_song_id" : "master_song.id"},
  async: false
  });
$.ajax({
  url: '/create_us_listen.json',
  data: { "user_song_id" : "user_song.id"},
  async: false
  });
  .....

Which goes to my routes:

match "create_us_listen.json" => "song_listens#create"

match "create_ms_listen.json" => "song_listens#create_ms_listen"

I know my goal is to somehow set the listenable type and id in the SongListen table but so far they have both been nil. What am I doing wrong?

4

1 回答 1

3

这是错误的:

params[:listenable_id => :user_song_id]

你能看出为什么吗?

试试看:

def create
    @song_listen = current_user.song_listens.build(params[:song_listen]) do |sl|
        sl.listenable_id = params[:song_id]
    end
    @song_listen.save
end

不知道你是如何得到song_id的,但这就是想法。


$("#jpId").bind($.jPlayer.event.play, function(event) {
    // This event is fired when a song start playing,
    // so do your ajax request here.
    // Not sure how to get the id of your song.
    // You can access your media with event.jPlayer.status.media,
    // and from there, get the name or id of your song I guess
});
于 2012-05-07T19:39:07.907 回答