将实例变量从另一个模型传递到表单中

时间:2015-12-08 15:42:29

标签: ruby-on-rails ruby-on-rails-4 form-for nested-form-for

我已经尝试了几天解决这个问题,但没有运气。

我正在开发一个包含4个模型的webapp;用户,投票,参数和评级。评级模型假设负责对参数进行评级。

协会是:

class Rating < ActiveRecord::Base
  belongs_to :user
  belongs_to :argument
end

class Vote < ActiveRecord::Base
    has_many :vote_options, dependent: :destroy
    has_many :arguments
    accepts_nested_attributes_for :vote_options, :reject_if => :all_blank, :allow_destroy => true

class Argument < ActiveRecord::Base
  belongs_to :user
  belongs_to :vote
  has_many :ratings

class User < ActiveRecord::Base

  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable, 
         :omniauthable, :omniauth_providers => [:facebook]
  has_many :uservotes, dependent: :destroy
  has_many :vote_options, through: :uservotes
  has_many :arguments, through: :votes
  has_many :ratings

我的问题是我试图在评级视图中访问@argument,以便传递被评级的当前参数的argument.id。

    _argument.html.erb

<% @vote.arguments.each do |argument| %>
    <%= div_for(argument) do |argument| %>
            <div class="col-md-4">
                <div class="well clearfix">

                    <div class="col-md-12">
                        <h2><%= argument.title %></h2>
                    </div>

                    <div class="col-md-8">
                        <p><%= argument.argument %></p>
                    </div>

                    <div class="col-md-4">
                        <div class="col-md-12">
                            <%= image_tag argument.user.picture, class: 'img-responsive' %>
                        </div>
                        <div class="col-md-12">
                            <p>Af: <%= argument.user.first_name %></p>
                        </div>
                    </div>
                    <div class="col-md-12">
                        <%= render 'ratings/rating' %>
                    </div>

    <% end %>

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

<% end %>

这很好,但部分im渲染(评级)不会采用@argument实例变量。

_rating.html.erb

<%= form_for ([@argument, @argument.ratings.new]), as: :post, url: new_rating_path(@argument), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %>

  <fieldset class="rating">
    <h1><%= @argument.id %></h1>

    <%= f.radio_button :score, '5', class: 'star', id: "star5_#{@argument.id}", value: 5 %>
    <%= f.label 'a', class: "full", for: "star5_#{@argument.id}" %>

    <%= f.radio_button :score, '4', class: 'star', id: "star4_#{@argument.id}", value: 4 %>
    <%= f.label '', class: "full", for: "star4_#{@argument.id}" %>

    <%= f.radio_button :score, '3', class: 'star', id: "star3_#{@argument.id}", value: 3 %>
    <%= f.label '', class: "full", for: "star3_#{@argument.id}" %>

    <%= f.radio_button :score, '2', class: 'star', id: "star2_#{@argument.id}", value: 2 %>
    <%= f.label '', class: "full", for: "star2_#{@argument.id}" %>

    <%= f.radio_button :score, '1', class: 'star', id: "star1_#{@argument.id}", value: 1 %>
    <%= f.label '', class: "full", for: "star1_#{@argument.id}" %>



  </fieldset>
  <div class="actions">
    <%= f.submit 'Rate', class: 'btn btn-primary' %>
  </div>
<% end %>

我想在form_for中使用它,并且能够使用css类的字符串字符串插值来访问它。

我做了一些事情来解决这个问题: 我在投票控制器中添加了一个before_action,其中我是set_argument。这使得访问@argument实例变量成为可能,但它似乎只是采用了第一个参数,因此它们都具有相同的ID。

def set_argument
  @argument = Argument.find_by(params[:id])
end

如何在表单中包含@argument实例变量?将argument.id和user.id传递给评级模型? 当前代码给出了这个错误:     未定义的方法`humanize'代表nil:NilClass

此外,在提交评级表时,还有路线错误,我不知道为什么会这样。

我的路线文件如下所示:

Rails.application.routes.draw do

  devise_for :users, controllers: { omniauth_callbacks: "users/omniauth_callbacks", registrations: 'users' }
  devise_scope :user do 
    resources :users, only: [:show]
  end

  root 'votes#index'
  resources :votes do
    resources :arguments
  end
  resources :uservotes, only: [:create]
  resources :ratings

我希望有人能够帮助我(或指导我朝着正确的方向前进) 提前谢谢!

用于向投票添加参数的_form:

<%= form_for([@vote, @vote.arguments.new]) do |f| %>

<p><%= f.label :Bruger %><br>
<%= current_user.first_name %>

<p><%= f.label :Titel %><br>
<%= f.text_field :title, placeholder: "Skriv en overskrift" %></p>
<p><%= f.label :Argument %><br>
<%= f.text_area :argument, cols: 35, rows: 6, placeholder: "Max 250 tegn" %>

  <p><%= f.submit 'Opret', class: 'btn btn-primary' %></p>
<% end %>

2 个答案:

答案 0 :(得分:0)

您应该将参数作为local传递给_argument.html.erb中的render部分:

<%= render 'ratings/rating', locals: { argument: argument }  %>

然后你的_rating.html.erb部分会有:

<%= form_for ([argument, argument.ratings.new]), as: :post, url: new_rating_path(argument), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %>

  <fieldset class="rating">
    <h1><%= argument.id %></h1>

    <%= f.radio_button :score, '5', class: 'star', id: "star5_#{argument.id}", value: 5 %>
    <%= f.label 'a', class: "full", for: "star5_#{argument.id}" %>

    <%= f.radio_button :score, '4', class: 'star', id: "star4_#{argument.id}", value: 4 %>
    <%= f.label '', class: "full", for: "star4_#{argument.id}" %>

    <%= f.radio_button :score, '3', class: 'star', id: "star3_#{argument.id}", value: 3 %>
    <%= f.label '', class: "full", for: "star3_#{argument.id}" %>

    <%= f.radio_button :score, '2', class: 'star', id: "star2_#{argument.id}", value: 2 %>
    <%= f.label '', class: "full", for: "star2_#{argument.id}" %>

    <%= f.radio_button :score, '1', class: 'star', id: "star1_#{argument.id}", value: 1 %>
    <%= f.label '', class: "full", for: "star1_#{argument.id}" %>



  </fieldset>
  <div class="actions">
    <%= f.submit 'Rate', class: 'btn btn-primary' %>
  </div>
<% end %>

编辑:因为它是渲染的唯一参数,你可以这样做:

<%= render 'ratings/rating', argument: argument  %>

答案 1 :(得分:0)

您实际上是在传递@vote对象,并且参数通过ActiveRecord关联附加。 这是传递参数的方法......

<%= render 'ratings/rating', vote: @vote  %>

然后,如果你需要将参数传递给另一个部分......

# no '@' since you got it from votes.
<%= render 'ratings/rating', argument: argument %>

然后在参数的部分中丢失@ ...

<%= form_for ([argument, argument.ratings.new]), as: :post, url: new_rating_path(argument), method: :patch, html: { class: "edit_post", id: "edit_post_45" } do |f| %>