fields_for not rendering association name (belongs_to relationship) - ruby-on-rails-3

I'm trying to create the form to create an event. Events belong_to a creator (of class user), and the form includes fields_for the creator.
Largely the form is working - it renders everything else properly, and the create action processes it properly when the fields_for #event.creator section is commented out. The fields_for tag is rendering event[user] tags instead of event[creator], though, and i can't figure out why. Ideas? Here are the relevant excerpts.
(in views/events/new.html.erb)
<%= form_for #event do |form| %>
<%= render :partial => '/events/form', :object => form %>
<%= form.submit 'Go!' %>
<% end %>
(in events/_form.html.erb)
...
<% if !signed_in? %>
To create your event, please provide an email address and create a password. <br />
<%= form.fields_for #event.creator do |uf| %>
<div class="email_field">
<%= uf.label :email %>
<%= uf.text_field :email, :type => "email" %>
</div>
...
<% end %>
<% end %>
(controllers/events_controller.rb)
def new
#event = Event.new
if !signed_in?
#event.build_creator
end
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #event }
end
end
(models/event.rb)
belongs_to :creator, :class_name => "User"
accepts_nested_attributes_for :creator
Largely this works, but the form elements render as
<div class="email_field">
<label for="event_user_email">Email</label>
<input id="event_user_email" name="event[user][email]" size="30" type="email" />
</div>
<div class="password_field">
<label for="event_user_password">Password</label>
<input id="event_user_password" name="event[user][password]" size="30" type="password" />
</div>
...
the issue here is event_user and event[user] instead of event_creator and event[creator]; when i submit the form i get an error that event doesn't have a User field.

<%= form.fields_for :creator, #event.creator do |uf| %>

Related

Search in joint table

i need some help to put a search field on my view.
I got a families table, and each family got 0-n books. I want to make a search that only families of a specific book are show.
Right now i am using ransack for some other simple searches:
Controler:
class FamiliesController < ApplicationController
def index
#search = Family.search(params[:q])
#families = #search.result
respond_to do |format|
format.html # index.html.erb
format.json { render json: #families }
end
end
model:
class Family < ActiveRecord::Base
has_many :names
has_and_belongs_to_many :books, :join_table => "books_families"
has_and_belongs_to_many :races, :join_table => "families_races"
attr_accessible :descr, :nome, :book_ids, :race_ids
validates :nome, uniqueness: true, presence: true
end
View:
<fieldset>
<legend>Filter for families</legend>
<%= search_form_for #search do |f| %>
<div class="field">
<%= f.label :nome, "Name: " %><br />
<%= f.text_field :nome_cont, :class => "search-field"%>
</div>
<div class="actions">
<%= f.submit "Search" %>
</div>
<% end %>
</fieldset>
<table>
<tr>
<th><%= sort_link(#search, :nome, "Name") %></th>
<th>Books</th>
<th>Descr</th>
</tr>
(...)
<td>
<ol type="disc">
<% family.books.each do |book| %>
<li> <%= book.nome %> </li>
<% end %>
</ol>
</td>
(...)
What should i do?
I'm not familiar with ransack, but your query should be achievable with SQL. I don't know your all of your table/field names, but something like this should work.
#families = Family.where("families.id IN(SELECT books_families.family_id FROM
books_families WHERE books_families.book_id IN(
SELECT books.id FROM books WHERE books.title LIKE(?)))",
"%" + params[:q] + "%")
Finally got the solution. its a simple 2 line thing:
<div class="field">
<%= f.label :books_id_eq, "Livro:" %><br />
<%= f.collection_select :books_id_eq, Book.order(:nome), :id, :nome, :include_blank => "Todos" %>
</div>

Pass a variable to text_field without changing form

I have _form.html.erb
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :password %>
<%= f.password_field :password %>
Now if I render this form in homepage, HTML code should be:
<label for="session_name">Name</label>
<input id="session_name" name="session[name]" size="30" type="text">
...
If I change my _form.html.erb to:
<%= f.label :name %>
<%= f.text_field :name, disabled: true %>
...
HTML code should be:
...
<input disabled="disabled" id="session_name" name="session[name]" size="30" type="text">
...
But, I don't want to change my _form.html.erb, so how can I pass the disabled: true into my form? I tried to use render partial: but don't know syntax.
I just learn Ruby on Rails for 2 weeks, so please help me.
i donno why u wnt to do so but u can solve the prob by this method. Try doing-
in application helper, add method -
def add_disabled
#i suppose that u want the field to be disabled in the users controller for edit action but not for other controllers or actions
return "disabled='disabled'" if params[:controller] == "users" and params[:action] == "edit"
end
in _form.html.haml
= f.text_field :name, #{add_disabled}
this will call the helper method and return "disabled='disabled'" depending upon the controller and action

Rails - routing when nesting with rails - beginner

I am relatively new to programming and to rails so please be indulgent:)
I am building a website for myself which contains a blog. I have two models that are nested and I do not seem to understand how to use REST to perform certain actions on my articles and comments.
When I create a comment if the comment doesn't pass validation I want it to render the page again so that the user can correct his mistakes and resubmit the comment. When I try to render, it gives me a missing template error.
Here is the code:
You can also find this code on github --> https://github.com/MariusLucianPop/mariuslp-
routes.rb
Mariuslp::Application.routes.draw do
get "categories/new"
root :to => "static_pages#index"
match "login" => "visitors#login" # not rest
match "logout" =>"visitors#logout" # not rest
match "comment" => "articles#show"
resources :articles do
resources :comments
end
resources :tags, :taggings, :visitors, :categories, :comments
end
articles_controller.rb
def show
#article = Article.find(params[:id])
#comment = #article.comments.new
end
comments_controller.rb
def create
article_id = params[:comment].delete(:article_id)
#comment = Comment.new(params[:comment])
#comment.article_id = article_id
if #comment.save
redirect_to article_path(#comment.article_id)
else
render article_path(#comment.article_id,#comment) ## This one doesn't work
end
end
def new
#comment = Comment.new
end
def destroy
Comment.find(params[:id]).destroy
redirect_to articles_path()
end
Views-articles:
_comment.html.erb
<div class="comment">
<%= comment.body %><br />
<%= link_to "Delete Comment", article_comment_path(#article), :method => :delete, :confirm => "Are you sure you want to delete this comment?" %>
</div>
_comment_form.html.erb
<%= form_for #comment do |f|%>
<%= f.hidden_field :article_id%>
<%= f.label :body %><br />
<%= f.text_area :body, :cols => 50, :rows => 6 %><br />
<%= f.submit%>
<%end%>
show.html.erb
<p><%= link_to "<< Back to Articles", articles_path%></p>
<div class = "article_show">
<%= label_tag :category_id %>
<%= #article.category_id%> <br />
<%= label_tag :title%>:
<%= #article.title%> <br />
<%= label_tag :body%>:
<%= #article.body%> <br />
<%= label_tag :tag_list%>:
<%= #article.tag_list%><br />
</div>
<br />
<% if session[:username]== "marius"%>
<div class ="admin">
<%= link_to "Edit", edit_article_path(#article)%>
<%= link_to "Delete", article_path(#article), :method => :delete, :confirm => "Are you sure you want to delete this article ?"%>
</div>
<%end%>
<br />
<%= render :partial => 'comment', :collection => #article.comments %>
<%= render :partial => 'comment_form'%>
Have you tried to use where you point the problem?
render 'articles/show'
You don't need to use article_comment_path because that is a full path, not just the place where you store the view templates. In this case, you only need the view. Of couse you must be sure to get all instance variable which you use in this views.
UPDATE:
#article = Articles.find(article_id)
render 'articles/show'

Rails form submitted multiple times but don't know why

I have a form as follows:
<%= form_for(:session, :url => sessions_path, :remote => true, :html => {:id => 'login_form'}) do |f| %>
<div class="formRow">
<%= f.label :email %><br>
<%= f.text_field :email, :value => (#email if #email) %>
</div>
<div class="formRow">
<%= f.label :password %><br>
<%= f.password_field :password %>
</div>
<div class="formRow small">
<%= link_to "I forgot my password",'#' %>
</div>
<div class="formRow">
<%= f.submit signin_button_text, :class => "button-big left" %>
</div>
<% end %>
It goes to this controller:
def create
#email = params[:session][:email]
user = User.authenticate(params[:session][:email],params[:session][:password])
respond_to do |format|
if user.nil?
#title = "Sign in"
flash.now[:error] = "Invalid email/password combination"
format.js {render :action => :new }
else
sign_in user
format.js {render :action => :create }
end
end
end
Here is the new.js file:
$('#login_form').replaceWith("<%=escape_javascript(render 'login_form')%>");
if($('.flash-block').length ==0) {
$('#login_form').before("<div class='flash-block error'><span><%=escape_javascript(flash[:error])%></span></div>");
}
For some reason if the form is submitted with errors it loops four times.
I don't understand why.
Is there something in the code that causes this to loop?
I am assuming that you are using jquery. This is usually happened when there is an incomplete call or there is some sort of error and you haven't refresh the page. Try something like this:
<script type="text/javascript">
$('#login_form').submit(function() {
$(this).unbind('submit').submit();
});
</script>
I was using Fancybox and was not opening it in an iframe. So I wound up loading the jquery libraries twice and thus when I submitted the form I had multiple submissions.
Once I opened Fancybox in an iframe it submitted only once.

ActiveResource, a model, and Form_Tag

I am trying to use form_tag to pass the params captured by the form to my users controller. I am attempting to communicate with a Sinatra server, and so I do not have a database on the client. My view is as follows:
<% form_tag(#user) do %>
<div class="field">
<%= label_tag :first_mame %><br />
<%= text_field_tag :first_name %>
</div>
<div class="field">
<%= label_tag :last_name %><br />
<%= text_field_tag :last_name %>
</div>
<div class="field">
<%= label_tag :email %><br />
<%= text_field_tag "user[email]" %>
</div>
<div class="field">
<%= label_tag :device_id %><br />
<%= text_field_tag "user[device_id]" %>
</div>
<div class="field">
<%= label_tag :type %><br />
<%= text_field_tag "user[device_type]" %>
</div>
<div class="actions">
<%= submit_tag %>
</div>
<% end %>
The create action on my controller is simply:
def create
#user = User.new(params[#user])
#user.save
respond_to do |format|
if #user.save
format.html { redirect_to(#user, :notice => 'User was successfully created.') }
format.json {render :json => #user }
format.xml { render :xml => #user, :status => :created, :location => #user }
else
format.html { render :action => "new" }
format.xml { render :xml => #user.errors, :status => :unprocessable_entity }
end
end
end
Here's what I get as a result => expected an attributes Hash, got nil
Anybody know why? Thanks for the help.
You need to use form_for and not form_tag. form_for(#user) do
In your model you need to create a schema. Without it Rails doesn't know what do with the data you enter into the form.
When you pass the object into the parameter hash use :user and not #user. #user = User.new(params[:user])
For your form you need to do
<%= form_for #user do |f| %>
<div class="field">
<%= f.label :first_name %>
<%= f.text_field :first_name %>
</div>
# more fields
<% end %>
Note the:
<% %> --> <%= %>
form_tag(#user) do --> form_for(#user) do |f|
label_tag --> f.label
text_field_tag --> f.text_field
In you controller:
#user = User.new(params[:user])
Update:
<% %> --> <%= %>: This is just the convention in rails3, when ever you want to write something in the response you should use later(with = sign). Earlier still works but is deprecated.
form_tag(#user) do --> form_for(#user) do |f|
form_tag(#user) do: form_tag is used to for simple forms which are not tied with any model. You can have the tags inside form_tag named so that they resemble form for, but then why wouldn't you use form_for directly. Apparently the first parameter to the helper is target url, and in this particular case rails magically identifies the url from #user and you didn't notice any bug
form_for(#user) do |f|: form_for is used to create a form for a model, and ties up the form with the instance of the model passed to it. The block for form_for receives a form_builder object, which has equivalents of text_field_tag, label_tag etc. as text_field, label
label_tag --> f.label: first is the common tag which just creates a label tag with no magic attached to it.The later is related with the model object and follows different naming and id conventions, than former. It also ties up with the value of the field, i.e. if the field has an error(failed validation), your label will be surrounded by a div tag with class fields_with_error or something, I can't remember the class name.
text_field_tag --> f.text_field: Former will create a field with name first_name with no magic attached. The later follows a naming convention, the input field will be named user[first_name], so that when you do params[:user] you get a first_name parameter there. It also ties up with the value of the field with the html input, i.e. you get the same error functionality as label and you also get the input automatically prefilled with whatever the value field has in the model instance.