无法让'has_and_belongs_to_many'工作

时间:2013-09-11 10:01:45

标签: ruby-on-rails associations ruby-on-rails-4

之前发过一篇关于此事的帖子,但经过大量的测试和更改已经过时了。

我正在尝试将用户和活动联系在一起。(一个用户可以有多个活动。一个活动可以有多个用户)。我几乎是一个多用户议程。

每当我创建一个新活动时,我都可以通过复选框选择用户进行活动。

但是,我无法让它工作;用户不会出现在我的活动节目中。在我的节目中打印@ activity.users导致#<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_User:0x43d2158>但是循环它,或者检查我的活动.js什么都没显示(活动.js在活动中显示“用户”:[]。所以我很确定他们“没有正确联系。

以下是一些代码:

activities.js索引方法

  def index
    @activities = Activity.all
    respond_to do |format|
      format.html 
      format.js {render_json @activities.to_json(:include => [:pictogram ,:users]) }
    end
  end

活动表单(循环所有用户)

<%= form_for(@activity) do |f| %>
  <% if @activity.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@activity.errors.count, "error") %> prohibited this activity from being saved:</h2>

      <ul>
      <% @activity.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :title %><br>
    <%= f.text_field :title %>
  </div>
  <div class="field">
    <%= f.label :start_date %><br>
    <%= f.date_select :start_date %>
  </div>
  <div class="field">
    <%= f.label :end_date %><br>
    <%= f.date_select :end_date %>
  </div>

  <div class="users">
    <% for user in User.all %>
      <label class="activity">
        <%= check_box_tag "activity[user_ids][]", user.id %>
        <%= user.name %>
      </label>
    <% end %>
  </div>


    <div class="pictograms">

      <% for p in Pictogram.all  %>
        <% #f.fields_for :pictograms do |x| %>
          <%= p %>
        <% #end %>
      <% end %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

schema.rb

ActiveRecord::Schema.define(version: 20130911095113) do

  # These are extensions that must be enabled in order to support this database
  enable_extension "plpgsql"

  create_table "activities", force: true do |t|
    t.string   "title"
    t.date     "start_date"
    t.date     "end_date"
    t.integer  "pictogram_id"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  add_index "activities", ["pictogram_id"], name: "index_activities_on_pictogram_id", using: :btree

  create_table "activities_users", id: false, force: true do |t|
    t.integer "activity_id"
    t.integer "user_id"
  end

  add_index "activities_users", ["activity_id"], name: "index_activities_users_on_activity_id", using: :btree
  add_index "activities_users", ["user_id"], name: "index_activities_users_on_user_id", using: :btree

  create_table "pictograms", force: true do |t|
    t.string   "title"
    t.string   "url"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

  create_table "users", force: true do |t|
    t.string   "name"
    t.text     "avatar"
    t.date     "birthdate"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

end

Activity.rb

class Activity < ActiveRecord::Base
  belongs_to :pictogram
  has_and_belongs_to_many :users

  accepts_nested_attributes_for :pictogram, allow_destroy: false
  accepts_nested_attributes_for :users, allow_destroy: false
end

User.rb

class User < ActiveRecord::Base
    has_and_belongs_to_many :activities

    validates_presence_of   :name, :on => :create
    validates_presence_of   :birthdate, :on => :create

    accepts_nested_attributes_for :activities, allow_destroy: false
end

活动来自我的活动控制器

def activity_params
  params.require(:activity).permit(:title, 
                                  :start_date, 
                                  :end_date, 
                                  :users,
                                  :pictogram)
end

3 个答案:

答案 0 :(得分:4)

试试这样:

class Activity < ActiveRecord::Base
  belongs_to :pictogram
  has_and_belongs_to_many :users

  accepts_nested_attributes_for :pictogram, allow_destroy: false

  def user_ids=(values)
    self.users << User.find(values)
  end
end

#controller

def activity_params
  params.require(:activity).permit(:title, 
                                  :start_date, 
                                  :end_date, 
                                  {:user_ids =>[]},
                                  :pictogram)
end

答案 1 :(得分:1)

我建议你先尝试一些简约的调试,

User.create!(...)         # create a valid user record
Activity.create!(...)     # same as above
User.all.first.activities << Activity.all.first
User.all.first.activities.any?

看看这是否有效,还要关注你的join_table并检查实际记录是否持久存在。您的架构也很好。

答案 2 :(得分:0)

我认为,他们都没有读过strong_parameters with nested attributes

您可以在nested_attributes的许可参数中轻松定义:users_attributes

活动控制器:

def activity_params
  params.require(:activity).permit(:title, 
                                  :start_date, 
                                  :end_date, 
                                  users_attributes: [:id])
end

这是执行此操作的理想方式。感谢