form_for 用于多对多关系类型的关系表

发布于 2024-10-15 16:28:31 字数 3192 浏览 1 评论 0原文

我的目标是为用户和特定项目的每个关系显示选择框。 需要列出所有用户,但只有项目用户具有某种类型的关系。其他用户在其选择框中没有选择任何内容。

我有这个模型:

class Project < ActiveRecord::Base
    belongs_to :company
    has_many :tasks, :order => 'state_type_id ASC'

    has_many :project_user_relations
    has_many :users, :through => :project_user_relations

    def t_name
       name.camelcase
    end
end

class User < ActiveRecord::Base
    belongs_to :company

    has_many :tasks , :foreign_key => :assigned_user_id 

    has_many :project_user_relations
    has_many :projects, :through => :project_user_relations

    def full_name
     firstname + ' ' + lastname
    end

    def relation_to(project)
     relation=ProjectUserRelation.find_by_project_id_and_user_id(project.id, id)
     relation ||= relation=ProjectUserRelation.new
    end
end

class ProjectUserRelation < ActiveRecord::Base
    belongs_to :project
    belongs_to :user
    has_one :project_user_relation_type
end

class ProjectUserRelationType < ActiveRecord::Base
    def t_name
        I18n.t("app.projects.users.relation.type."+code)
    end
end

我想制作一个表单来显示所有用户,并使用collection_select。 使用了代码:

def edit_all
   @project = Project.find(params[:project_id])
   @users = User.all
....

我在我的控制器中 路线工作正常。

在我看来:

<% @users.each do |user| %>
   <%= f.fields_for :users, user do |user_fields| %>
     <tr class="reference" rel="<%=  parent_user_path(user)  %>" >
        <td class="name"><%= link_to user.full_name, parent_user_path(user) %></td>
        <td class="email"><%= mail_to user.email %></td>
        <td class="type">
            <%= user_fields.fields_for user.relation_to @project do |relation_fields| %>
                <%= relation_fields.collection_select :project_user_relation_type, ProjectUserRelationType.all, :id, :t_name, {:include_blank => false, :prompt => t("helpers.select.prompt") } %>
            <%  end %>
         </td>
      </tr>
   <% end %>      
<% end %>     

或用于测试:

<%= f.fields_for :users, @users do |xuser_fields| %>
    <% logger.debug "#{self.to_s} xuser_fields = #{xuser_fields.object.inspect} ;" %>
    <tr>
       <td><%= xuser_fields.text_field :firstname %></td>
       <td></td>
       <td></td>
       <td></td>
    </tr>
<% end %>

但不行,

第一个在html中生成错误的名称:

select id="project_users_project_user_relation_project_user_relation_type" name="project[users][project_user_relation][project_user_relation_type] “

第二个生成错误: undefined method `firstname' for # Array:0x4d03658

你能帮我解决这个情况吗?

PS:抱歉代码很长:(


解决方案(可能 - 通过阅读 RoR 源代码解决)

我找到了解决方案。

项目模型中的一个方法

def name_attributes=(attributes)
    # Process the attributes hash
end

丢失了。

这是令人难以置信的解决方案:]。 fields_for: :name, @some_collection 之后还有精确的语法,其中 name 必须与模型中提到的 def 开头的名称完全相同。

My goal is to display select box for each relation for users and specific project.
All users need to be listed but only project users have some type of relation. Other users have none selected in theirs select box.

I have this model:

class Project < ActiveRecord::Base
    belongs_to :company
    has_many :tasks, :order => 'state_type_id ASC'

    has_many :project_user_relations
    has_many :users, :through => :project_user_relations

    def t_name
       name.camelcase
    end
end

class User < ActiveRecord::Base
    belongs_to :company

    has_many :tasks , :foreign_key => :assigned_user_id 

    has_many :project_user_relations
    has_many :projects, :through => :project_user_relations

    def full_name
     firstname + ' ' + lastname
    end

    def relation_to(project)
     relation=ProjectUserRelation.find_by_project_id_and_user_id(project.id, id)
     relation ||= relation=ProjectUserRelation.new
    end
end

class ProjectUserRelation < ActiveRecord::Base
    belongs_to :project
    belongs_to :user
    has_one :project_user_relation_type
end

class ProjectUserRelationType < ActiveRecord::Base
    def t_name
        I18n.t("app.projects.users.relation.type."+code)
    end
end

I want make a form to display all users, with collection_select.
I used code:

def edit_all
   @project = Project.find(params[:project_id])
   @users = User.all
....

in my controler
routes works ok.

in my view:

<% @users.each do |user| %>
   <%= f.fields_for :users, user do |user_fields| %>
     <tr class="reference" rel="<%=  parent_user_path(user)  %>" >
        <td class="name"><%= link_to user.full_name, parent_user_path(user) %></td>
        <td class="email"><%= mail_to user.email %></td>
        <td class="type">
            <%= user_fields.fields_for user.relation_to @project do |relation_fields| %>
                <%= relation_fields.collection_select :project_user_relation_type, ProjectUserRelationType.all, :id, :t_name, {:include_blank => false, :prompt => t("helpers.select.prompt") } %>
            <%  end %>
         </td>
      </tr>
   <% end %>      
<% end %>     

or for test:

<%= f.fields_for :users, @users do |xuser_fields| %>
    <% logger.debug "#{self.to_s} xuser_fields = #{xuser_fields.object.inspect} ;" %>
    <tr>
       <td><%= xuser_fields.text_field :firstname %></td>
       <td></td>
       <td></td>
       <td></td>
    </tr>
<% end %>

but notnihng woks right

first one generates wrong name in html:

select id="project_users_project_user_relation_project_user_relation_type" name="project[users][project_user_relation][project_user_relation_type]"

second one generates error:
undefined method `firstname' for # Array:0x4d03658

Can you help me to solve this situation.

PS:sorry for long code :(


SOLUTION (probably - solved by reading RoR sources)

I found sollution i thing.

A method

def name_attributes=(attributes)
    # Process the attributes hash
end

in Project model was missing.

It is unbelievable sollution :].
There is also exact syntax after fields_for: :name, @some_collection, where name must be exactly same name as in the beginign of mentioned def in Model.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文