MVC Html.ActionLink ignores the Controller parameter - model-view-controller

I have a a view that has the following code:
<h2><%= Model.Company.CompanyName %></h2>
<h3>Projects</h3>
<ul>
<%
foreach (Project p in Model.Company.Projects)
{
%>
<li><%= Html.ActionLink(p.ProjectName,"Details", "Projects", new {id=p.ProjectID,companyId=p.CompanyID}) %></li>
<%
}
%>
</ul>
<%= Html.ActionLink("Add Project", "Create", "Projects", new {id = Model.CompanyID}) %>
<br />
<h3>Users</h3>
I have a ProjectsController but when I run the application and click on the Add Project Link it expects to go to /Company/Create instead of /Projects/Create. Am I missing something?

You're matching the signature that expects the route values in the third parameter and the html attributes in the fourth. Add another parameter (null is ok) and you'll get the signature that has the link text, action, controller, route values, and html attributes.
<%= Html.ActionLink("Add Project",
"Create",
"Projects",
new {id = Model.CompanyID},
null ) %>

Related

Using carmen gem with rails

What I am trying to do is show the 2 letter abbreviation code of the countries, i.e 'US'.
After the country is selected I need to show its state or province.
but I am having a problem.
My code looks like
<%= f.select :country_code, region_options_for_select(only_us_and_france) %>
and define this in helper:
def only_us_and_france
Carmen::Country.all.select{|c| %w{US FR}.include?(c.code)}
end
I am using Rails 4.1.0.
I have solved this by :
Step1: Generated migration
rails g migration addStateCodeFieldToAccounts state_code:string
Step2: Define a method inside controller
def subregion_options
render partial: 'subregion_select'
end
Step3: Declare in routes
resources :accounts do
collection do
get 'subregion_options'
end
end
Step4: In view
<div class="input-control select state_input" data-role="input-control">
<%= f.select :country, region_options_for_select(only_us_and_france) %>
</div>
<div class="input-control select state_input" data-role="input-control">
<%= render partial: 'subregion_select', locals: {parent_region: f.object.country} %>
</div>
Step5: Make partial subregion_select
<div id="account_state_code_wrapper">
<% parent_region ||= params[:parent_region] %>
<% country = Carmen::Country.coded(parent_region) %>
<% if country.nil? %>
<em>Please select a country above</em>
<% elsif country.subregions? %>
<%= subregion_select(:order, :state_code, parent_region) %>
<% else %>
<%= text_field(:order, :state_code) %>
<% end %>
</div>
Step6: In my js file written this
$('select#account_detail_country').change(function(){
selectWrapper = $('#account_state_code_wrapper')
countryCode = $(this).val()
url = "/account_details/subregion_options?parent_region="+countryCode
console.log(url)
selectWrapper.load(url)
});
yeah and it works :) Hope this will help you.

Passing parent model's id to child's new and create action on rails

My project has 2 models, Company and Product. Company has many products and products belongs to company. I want to put a link to Product's new action on a Company show page and pass company_id to Product new action so that the new product automatically belongs to the company from which it linked.
How should I change below codes to make this happen?
My environment is ruby 2.0.0 and rails 4.0.2
show.html.erb(Companies)
<%= link_to "Add new product", new_product_path(company_id: #company) %>
products_controller.rb
def new
#product = Product.new(params[:company_id])
end
def create
#product = Product.new(product_params, params[:company_id])
if #product.save
flash[:success] = "Product successfully created."
redirect_to #product
else
render 'new'
end
end
new.html.erb(products)
<% provide(:title, 'New product') %>
<h1>Add a new product</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(#product) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label :name, "Product Name" %>
<%= f.text_field :name %>
<%= f.label :description, "Description" %>
<%= f.text_area :description %>
<%= f.label :type, "Product Type" %>
<%= f.text_field :type %>
<%= f.label :released_date, "Released Date" %>
<%= f.date_field :released_date %>
#I want to omit below 2 lines by passing company_id from company show action
<%= f.label :company_id, "Company ID" %>
<%= f.text_field :company_id %>
<%= f.submit "Submit", class: "btn btn-large btn-primary" %>
<% end %>
</div>
</div>
:comapny_id is passed to product new action as shown in URL.
http://localhost:3000/products/new?company_id=6
Also shown in debug log.
company_id: '6'
action: new
controller: products
I think your error lies in the way you create the new product in the new action. At the moment it only passes the company id itself to the constructor, but you are not telling rails wich property should be set with it.
If you change it to #product = Product.new(company_id: params[:company_id]), then your new product object should have the company id and it should be filled in in the create form. Then, instead of omitting the fields you could just use a hidden field. Like this, there is no extra field for the company_id but it is still automatically added to the product_params and #product = Product.new(product_params) will create a product with a company_id.

add form (non-nested) dynamically in rails

pls can someone explain how I can dynamically add another copy of a form in rails?...been working on this for almost 2hrs. I messed around with .clone() and .appendTo in jquery, but it didnt work. Also, most of the materials I found online (like on railscast #196 and stackoverflow) focused heavily on nested forms. My form is nested, but I actually just want to add the parent form again. The photos which are nested use the html multiple attributes so I'm guessing that will handle multiple files upload for each parent form (btw I'm using paperclip).
If I just need to modify the railscast code please let me know.
Thanks.
<%= form_for(#user_book, html: { multipart: true }) do |f| %>
<% if #user_book.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user_book.errors.count, "error") %> prohibited this user_book from been saved:</h2>
<ul>
<% #user_book.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<p>hello</p>
<% end %>
</ul>
</div>
<% end %>
<%= f.text_field :title, placeholder: "enter title...", id: "book_title" %>
<%= f.text_field :category, placeholder: "enter category..." %>
<%= file_field_tag 'user_book[user_book_photos_attributes][][photo]', :multiple => true do |p| %>
<%= p.file_field :photo %>
<% end %>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

Rails how can I put <%= link_to ...%> into an instance variable?

I have this (and other) navigation links:
<li><%= link_to "Actors with commas", actor_path('search')+'/commas' %></li> |
These need to be put into the header part of my templates and they change based on the view template.
So in application.html.erb I have this:
<div class='submenu'>
<%= #app_menu %>
</div> <!-- end submenu -->
And in the view template I have:
#app_menu =
The question is, how do I put the top line (with the link_to, etc) into that instance variable and have Rails parse it properly with the HTML and without errors. Right now if I include <ul><li> it prints them out literally. And, of course, if I include <%= link_to... I get all sorts of errors.
Or is there perhaps a better way?
What I ended up doing was creating partials for each menu, so one partial _actors_menu.html.erb might look like this:
<%= image_tag "submenu-separation.png", :alt => 'separator' %> <li><%= link_to "Actors with commas", actor_path('search')+'/commas' %></li> <%= image_tag "submenu-separation.png", :alt => 'separator' %>
<li><%= link_to "Actors with Ampersand (&)", actor_path('search')+'/acute' %></li> <%= image_tag "submenu-separation.png", :alt => 'separator' %>
Then I put #app_menu = "actors_menu" on each actor view. And so on for the other pages.
But I'm wondering if there is a smarter way to do all this?
Also, where and how would I set a global variable for the app_menu so as not to repeat it in every template?

Where can I find the default Object.cshtml Editor template?

I need to modify the default editor template for scaffolding but I havent found the Object.cshtml template, where can I find the default razor Object.cshtml Editor template?
The following blog post describes how to customize the editor templates: http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-4-custom-object-templates.html
Basically you have to add a file named Views\Shared\EditorTemplates\Object.cshtml and put all the logic for displaying the object there.
When #marcind says they're compiled in, the templates themselves are not embedded but are rather written in code. For example, EditorFor calls TemplateFor which may call TextAreaExtensions.TextArea or one of many other extensions which generate the code that is ultimately output. This may be because the we have the option of removing the default view engine and using something like nhaml.
The mapping between the template names and the function creating the resulting output can be seen in System.Web.Mvc.Html.TemplateHelpers. See also System.Web.Mvc.Html.DefaultEditorTemplates.
The closest thing that exists right now are the Webforms templates that exist in Mvc3Futures which are available on the aspnet.codeplex.com website. Within it exists an DefaultTemplates\EditorTemplates folder that contains the templates.
Here's the Object.ascx template:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<script runat="server">
bool ShouldShow(ModelMetadata metadata) {
return metadata.ShowForEdit
&& metadata.ModelType != typeof(System.Data.EntityState)
&& !metadata.IsComplexType
&& !ViewData.TemplateInfo.Visited(metadata);
}
</script>
<% if (ViewData.TemplateInfo.TemplateDepth > 1) { %>
<% if (Model == null) { %>
<%= ViewData.ModelMetadata.NullDisplayText %>
<% } else { %>
<%= ViewData.ModelMetadata.SimpleDisplayText %>
<% } %>
<% } else { %>
<% foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => ShouldShow(pm))) { %>
<% if (prop.HideSurroundingHtml) { %>
<%= Html.Editor(prop.PropertyName) %>
<% } else { %>
<% if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString())) { %>
<div class="editor-label"><%= Html.Label(prop.PropertyName) %></div>
<% } %>
<div class="editor-field"><%= Html.Editor(prop.PropertyName) %> <%= Html.ValidationMessage(prop.PropertyName, "*") %></div>
<% } %>
<% } %>
<% } %>

Resources