has_one并且属于形式

时间:2015-11-12 10:01:43

标签: ruby-on-rails belongs-to has-one

我对rails非常陌生,而且我坚持使用has_one和belongs_to表单。我尝试通过表单创建一个有两个发言人(来自班级'用户')的团队,方式如下:

class Team<ActiveRecord::Base

belongs_to :league
belongs_to :seed
has_many :speakers do 
def user(level="1")
    find_by(level: level).user
end

端     端

我的用户模型如下所示:

class User < ActiveRecord::Base

belongs_to :team

end

用户模型:     类用户

演讲者模特:

class Speaker < ActiveRecord::Base
    belongs_to :team
    belongs_to :user
end

我的问题是(我认为)主要在我的控制器和form.controller看起来像:

class TeamsController<ApplicationController


def new
    @seed=Seed.find_by_id(params[:seed_id])
    @league=current_admin.league
    @team=current_admin.league.teams.build(:seed_id=>@seed,:approved=>false)
    @usernames= @mca.connections.connected.each do |x| x.user end
end

def create
    @league=current_admin.league
    @team = @league.teams.build(team_params)

  if @team.save
    flash[:notice] = "Team Request Sent!."
    redirect_to '/'
  else
    flash[:error] = "Unable to request team."
    redirect_to :back
  end

表格如下:

<div class="panel-body">
    <div class="container">
        <%= form_for @team do |f| %>
            <%= f.hidden_field :seed_id, :value => @seed.id %>
            <%= f.hidden_field :league_id, :value => @league.id %>

            <div class="row">
                <!-- <div class="col-md-8"> -->
                <div class="form-group">

                    <%= f.collection_select :speaker, @usernames,:user,:fullname, multiple:true %>
                </div>



                <!-- </div> -->
            </div>


            <div class="actions">
                <%= f.submit "Create" , class:"btn btn-primary" %>
            </div>

        <% end %>
    </div>
</div>

我真的很感激一些帮助,因为它不断抛出以下错误:

TeamsController中的NoMethodError #create 未定义的方法`每个&#39; for&#34; 2&#34;:String

1 个答案:

答案 0 :(得分:1)

您遇到的表面问题是,当Rails期待对象时,您正在传递字符串

  

用户(#69980837338020)预期,得到字符串(#69980808947560)

这意味着您应该发送@user而不是&#34;用户名&#34;等

错误可能就在这一行:

@team = @league.teams.build team_params 

...这意味着当您传递:speaker外键时,您正在传递speaker_id(Rails需要作为对象)。 Yury Lebedev的答案解释了如何执行此操作。

还有一个更深层次的问题。

我不知道每个User只能属于Team

class AddFieldsToUser < ActiveRecord::Migration
  def change
    add_column :users, :speaker_id, :integer
    add_column :users, :speaker2_id, :integer
  end
end

要实现此目的,您的用户才能成为一个团队的成员。

虽然这可能适用于规模较小的产品,但我个人认为这是一种不正确的架构设置。

如果任何,您希望team拥有speaker_1speaker_2,这意味着这两个选项存储在{ {1}}数据库(非用户)。

我认为是导致您出现问题的原因(当他们不存在时,您试图设置teamsspeaker_1参数speaker_2 db)。

-

我会推荐以下内容:

teams

这将使您能够致电:

#app/models/user.rb
class User < ActiveRecord::Base
   has_many :speaking_engagements, class_name: "Speaker"
   has_many :teams, through: :speaking_engagements
end

#app/models/speaker.rb
class Speaker < ActiveRecord::Base
   #columns team_id | user_id | level | created_at | updated_at
   belongs_to :team
   belongs_to :user
end

#app/models/team.rb
class Team < ActiveRecord::Base
   has_many :speakers do
      def user(level="1")
         find_by(level: level).user
      end
   end
end

要保存它,您将能够使用以下内容:

@team = Team.find params[:id]
@speakers = @team.speakers

@user.speaking_engagements.where(team: @team)

这应该允许您定义以下内容:

#app/controllers/teams_controller.rb
class TeamsController < ApplicationController
   def new
      ...
       @team = current_admin.league.teams.build seed: @seed, approved: false
   end

   def create
       @league = current_admin.league
       @team = @league.teams.build team_params

       if @team.save
         ...
   end

   private

   def team_params
       params.require(:team).permit(:name, :speakers) #-> not sure about "speakers"
   end
end