Rails 4 - Pre-Populate Form From Link - ruby-on-rails

I have a form that allows users to manually input movies to review. Additionally, I am pulling movies from an external API (TMDB). When the user searches, it shows all results from the database as well as another area where data is pulled from the API. I want them to be able to click on a thumbnail from the external API and pre-populate my "new" form with that data. This code currently goes to the "new" form, but the title and description are not populated like I want them to be (a blank new form is rendered).
<% if #movies_api %>
<div class="row">
<% #movies_api.each do |movie| %>
<% if movie.poster_path %>
<div class="col-sm-6 col-md-3">
<div class="thumbnail">
<%= link_to(image_tag('https://image.tmdb.org/t/p/w396' + movie.poster_path, class: 'image', size:"400x600"), {:action => 'new', :controller => 'movies'}, :title => movie.title, :description => movie.overview ) if movie.poster_path %>
</div>
</div>
<% end %>
<% end %>
<% end %>
How do I accomplish pre-populating the new form with data I gather from the API?

I figured out a way to do this. In my form, I can do:
<div class="field">
<%= f.label :title %><br>
<%= f.text_field :title, :value => params[:title] %>
</div>
Not sure if there is a better way, but this works :-)

Related

Rails - dynamically build nested object inside nested object partials (Cocoon)

Currently, I'm building a Medium-like blog service which users can add article parts(text, image, youtube...etc) that composite the article body.
Article model has many ArticlePart model and to create nested form dynamically, I'm using cocoon gem.
Here's my current code.
_form.html.erb
<%= link_to_add_association("Add New Article Part", f, :article_parts,{:data => {"association-insertion-node" => "#article" }}) %>
<ul class="sortable">
<div id="article">
<%= f.fields_for :article_parts %>
</div>
</ul>
_article_part_fields.html.erb
<li class="nested-fields">
<h2>Text Part</h2>
<%= f.hidden_field :position %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= link_to_remove_association("Delete part", f) %>
<h2>Insert New Article Part Here</h2>
</li>
Above works fine but what I want to do is to display "link_to_add_association" where "Insert New Article Part Here" blocks in _article_part_fields.html.erb so that users can add new article part anywhere they want to.
I tried to do it as below by passing parent object form to nested object form, but this code causes stack level too deep error.
<li class="nested-fields">
<h2>Text Parts</h2>
<%= f.hidden_field :position, :class => "position" %>
<%= f.label :title %>
<%= f.text_field :title, :class => "fld-name required" %>
<%= link_to_remove_association("Delete part", f) %>
<h2>Insert New Part Here</h2>
<%= link_to_add_association("商品", parent_form, :article_parts,{:render_options => {:locals => {:parent_form => parent_form}}, :data => {"association-insertion-node" => "#article" }}, :class => 'btn btn-ctrl btn-lg') %>
</li>
Any help appreciated to get this working, or suggest another way to achieve this.
Thanks in advance!

Processing two unassociated Rails models' forms in one controller action

I'm creating a Rails app that will take in input from two models and their respective forms, and then log into a website with Mechanize and do hundreds of tasks there.
The first form consists of the user's login information (the username and password, using the model User), and the second one is a long list of term names and their respective definitions (using the model Term and uploaded into the form as an Excel doc).
I have no need to associate these two models (unlike in similar SO questions, which seem to deal with nested models). Once this Mechanize task completes, I will destroy both models' objects from the database.
The two pieces of the app (logging in to the website; and uploading the terms and using them to interact with the website) both work perfectly in separate scripts.
My question is: How can I take in both models' information on one webpage and coordinate the controller(s) accordingly? In this situation, can I create both objects in one controller? (If not, that's fine, as long as there's an alternative; I'm game for whatever will get this to work.)
I'm posting some of my code below. I'm happy to answer any questions you may have. Please keep in mind I am pretty new at Rails, so is not very elegant code:
The User model:
class User < ActiveRecord::Base
attr_accessor :username, :password
end
And the Term model:
class Term < ActiveRecord::Base
attr_accessible :name, :definition
end
In my terms controller (the forms are located in the index action and the script is run in the show action):
def create
#term = Term.new(params[:term])
#user = User.new(params[:user])
if (#term.save && #user.save)
flash[:notice] = "Your terms have been sent for processing."
redirect_to terms_path
else
render :action => 'index'
end
end
def show
#term = Term.all
agent = Mechanize.new
page = agent.get('www.myurl.com')
#log into the website
#user.username = myform.field_with(:id => "userfield").value
#user.password = myform.field_with(:id => "passfield").value
#and then enter the term information into the website's forms
rest of Mechanize code goes here...
end
And in views/terms/index.html.erb:
#the login form:
<%= render 'loginform' %>
#the term file uploader:
<%= form_tag import_terms_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
<br>
<table id="terms">
<tr>
<th>Name</th>
<th>Definition</th>
</tr>
#displays the uploaded terms on the index page
<% #terms.each do |term| %>
<tr>
<td><%= term.name %></td>
<td><%= term.definition %></td>
</tr>
<% end %>
</table>
<p><%= link_to 'Update website with these terms', terms_update_terms_path %></p>
And in views/terms/_loginform.erb:
<%= form_for(#user) do |f| %>
<div class="field">
<%= f.label_tag(:username, 'Username') %><br />
<%= f.text_field_tag(:user, :username) %>
</div>
<div class="field">
<%= f.label_tag(:password, 'Password') %><br />
<%= f.password_field_tag(:user, :password) %>
</div>
<% end %>
And in views/terms/_termform.html.erb
<%= form_for(#term) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :definition %><br />
<%= f.text_area :definition %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
If you just need to save the data and truly don't want to associate the models, I would save the Term separately:
<%= form_for #user do |f| %>
<div class="field">
<%= f.label :username, 'Username' %>
<%= f.text_field :username %>
</div>
<div class="field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class="field">
<%= label_tag :name %>
<%= text_field_tag :name %>
</div>
<div class="field">
<%= label_tag :definition %>
<%= text_field_tag :definition %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
Then in your controller:
#term = Term.new
#term.attributes = {
:name => params[:name],
:definition => params[:definition]
}
#term.save
If you are adding multiple term fields to the form, I would consider something like Cocoon, and just add an each loop for saving the Terms in the controller.

Use form_for to save data in associated table

I am relatively new to rails - therefore the question should be very easy to answer. I tried to find a solution for the problem in other posts, but I could find it (probably because I don't know the right vocabulary right now).
Here is my question/ case:
I have two models:
1) Model one: Users
2) Model two: FreelancerData
They are connect through "User has one FreelancerData" and "FreelancerData belongs_to User". The FreelancerData contains three field "daily_rate", "status" and "user_id" (= foreign field).
Now I want to create a Form with form_for, in which I can fill in the FreelancerData for the current user.
I tried the following code, but this does not work
<% provide(:title, "Edit freelancer") %>
<div class="row">
<aside class="span4">
<section>
<%= render ('layouts/profile') %>
</section>
</aside>
<div class="span8">
<h1>Edit your profile</h1>
<h5>Please edit your current working status and your daily rate:</h5>
<%= form_for #user.freelancer_data do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :status %>
<%= f.select :status, ['Busy', 'Available'] %>
<%= f.label :daily_rate, "Daily rate in Euro ('.' and ',' are not allowed)" %>
<%= f.text_field :daily_rate %>
<%= f.submit "Save changes", class: 'btn-large btn-primary' %>
<% end -%>
<h5>If you want to change your picture, you can do it here:</h5>
<%= gravatar_for #user %>
change
</div>
</div>
So my question is: Is it possible to edit data of a associated table FreelancerData through the User Data?
Yup. You can use fields_for. Check out this link.

One click of the submit button in form_for results in 3 items in my database

I have a form in my rails app that creates an item in my database, but when I submit the form, it creates 3 items per click.
I have 2 other forms that add things to the same database, but they are on different pages, could that be related?
This is my form on the "new debate" page:
<%= form_for(#debate) do |f| %>
<div class="field">
<%= f.label :proposition %><br />
<%= f.text_field :proposition %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
I also have another form on the "show debate" page that appears twice:
<%= form_for(#debate.debates.create) do |support_form| %>
<div>
<%= support_form.label :content %><br />
<%= support_form.text_area :content %>
</div>
<%= support_form.hidden_field :is_supporting, :value => is_supporting %>
<div class="actions">
<%= support_form.submit %>
</div>
<% end %>
And when I click on the submit button on any of the 3 forms, I get 3 new debates.
I think your code, might be creating those extra records.
= form_for(#debate.debates.create) do |support_form|
If my assumption is correct .debates is an association, and you are creating that association with that line.
Try using build
= form_for(#debate.debates.build) do |support_form|

Work after user creation

I create a new user with basic fields as user name and password. Then I redirect to another page where the user is allowed to complete his profile. The page looks like this.
Ok, I created the user first. Then I redirected the user to complete his profile. The profile page looks like this
<h1>User successfully created</h1>
<h3>Would you like to complete your profile now?</h3>
<%= render #profile %>
<%= render #address %>
<%= button_to 'Save',{
:controller => "users",
:action => "update",
:id => #user.id,
:profile => #profile,
:address => #address
}, :method => :put %>
The code above executes the update action in the controller. However, I am getting nil for the #profile and #address objects. I guess the button_to is having no effect on the profile and address partials.
The address partial looks as follows
<%= form_for(#address) do |f| %>
<% if #address.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#address.errors.count, "error") %> prohibited this address from being saved:</h2>
<ul>
<% #address.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<fieldset>
<legend>Addresss</legend>
<div class="field">
<%= f.label :street_address %>
<%= f.text_field :street_address, :size => 40 %>
</div>
<div class="field">
<%= f.label :street_address_2 %>
<%= f.text_field :street_address_2, :size => 40 %>
</div>
<div class="field">
<%= f.label :city %>
<%= f.text_field :city, :size => 40 %>
</div>
<div class="field">
<%= f.label :state %>
<%= f.text_field :state, :size => 40 %>
</div>
<div class="field">
<%= f.label :zip_code %>
<%= f.text_field :zip_code, :size => 40 %>
</div>
<% end %>
I would appreciate if anyone would be able to help me on this.
The button_to method only creates a button which an be used to call an controller/ go to another page.
If you want to allow the user to modify fields, you need to use a form. Please read this guide on forms for more information, especially part 2 is of interest for your situation I guess.
Edit: You need a submit button in your form to submit it, not a button_to outside the form. If you want to have both partials submitted at the same time, you need 1 big form and a controller which is able to process the data of both models.

Resources