I'm creating a movie reviews website and setting multi languages translation.
Because of the translation, Movie API is needed to be switched to each language.
Now the API is defined on a model file though, I don't have any ideas that switching API.
Movie model
class Movie < ApplicationRecord
include HTTParty
self.primary_key = "id"
has_many :comments, dependent: :destroy
has_many :users, through: :comments
default_options.update(verify: false)
default_params api_key: '#API key', language: "en-EN" #swtiching needed for other languages.
format :json
~
end
Firstly, I tried using if and request.path.include? to place URL with English or other languages. But request command is not allowed to use on a model file.
How can I switching it? Any solutions?
Thanks.
You should create a method in your Model that accepts language as a parameter, and call that method from the Controller.
Related
I have a many to many polymorphic relationship:
class DocumentTask < ActiveRecord::Base
belongs_to :task
belongs_to :document, polymorphic: true
end
class Task < ActiveRecord::Base
has_many :documents, through: :document_tasks
end
class Contact < ActiveRecord::Base
has_many :tasks, though: :document_tasks, as: :document
end
class Service < ActiveRecord::Base
has_many :tasks, through: :document_tasks, as: :document
end
I have a URL that looks like this that sends information to the server:
/contacts/1/tasks?status_id_is=1&user_id_is=1
But sometimes it can look like this (since there is a polymorphic relationship):
/services/1/tasks?status_id_is=1&user_id_is=1
In my controller, I need to get the object of that polymorphic relationship. Typically, I can do the following:
document_id = params.detect {|name,_| name =~ /(.+)_id/}
#document = document_id[0].gsub("_id","").capitalize.constantize.find(document_id[1])
However, when the url contains a query string, this won't work because status_id_is and user_id_is will match the regular expression. An obvious solution would be to change the regex to /^(.+)_id$/ but who knows how many other use cases may arise.
Is there a nice way to achieve what I want? For example, something in the request object like request.association_parameter or params.association_parameter.
For filtering on a collection--like a search or the params you have to filter tasks--I can suggest an alternative approach which is to use params[:q] instead for filtering.
This is in line with "some" conventions for API filtering, like how ransack (gem) and ElasticSearch use q or query params, which is a wrapper param for scoping.
Equivalently, if following this approach, yours will look like below
/contacts/1/tasks?q[status_id_is]=1&q[user_id_is]=1
In this way, you will now have no problems looping in your params.detect because the status_id_is and user_id_is will be inside params[:q] and therefore is one-level deeper in the hash, which the params.detect loop will already no longer take into account. Thus any MODEL_id params will work for the polymorphic route.
I'm a beginner so the title of my question probably isn't very clear. For that reason, it has been difficult to find any solutions to the problem I'm having. I'm working on a language learning app that allows users to connect with native speakers who want to learn their language i.e. a native English speaker who is learning Italian and Spanish will be able to connect with native Italian and Spanish speakers who want to learn English.
I have a Language table that has the language name as a string and 2 join tables: Native and Desired. These both take user_id and language_id.
My models are set up like so:
class User < ActiveRecord::Base
has_many :natives
has_many :native_languages, through: :natives, source: :language
has_many :desireds
has_many :desired_languages, through: :desireds, source: :language
end
class Language < ActiveRecord::Base
has_many :native_speakers, through: :native_languages, source: :natives
has_many :desired_speakers, through: :desired_languages, source: :desireds
end
class Native < ActiveRecord::Base
belongs_to :user
belongs_to :language
end
class Desired < ActiveRecord::Base
belongs_to :user
belongs_to :language
end
I want to display matched users on the User index, so I need help with the query that should go within the index method on the users controller.
This is my first post here so let me know if I missed any critical pieces. Thanks in advance for any help!
Using subquery.
Native Speakers I desired
user = User.find(params[:id])
desired_lanuages = user.desired_languages
User.where(id: Native.select(:user_id).where(language: desired_lanuages))
Who want me
native_language = user.native_languages
User.where(id: Desired.select(:user_id).where(language: native_language))
Match
User.where(id: Native.select(:user_id).where(language: desired_lanuages))
.where(id: Desired.select(:user_id).where(language: native_language))
I do not try running code. But I think that kind of code is possible
Where is this "0" coming from in owners_attributes? Everything is working but this "0" key seems oddly out of place.. Is it normal/bug/or some setting? Leave it alone or remove it? Thanks!
Parameters: {"utf8"=>"✓", "shorturl"=>{"redirect"=>"http://www.test.com",
"owners_attributes"=>{"0"=>{"email"=>"adm#test.com"}}}...
Strong_params:
def shorturl_params
params.require(:shorturl).permit(:redirect, owners_attributes: [:email])
end
model:
class Shorturl < ActiveRecord::Base
has_many :campaigns
has_many :owners, through: :campaigns
accepts_nested_attributes_for :owners
...
That's the internal format for how these are ported over via HTTP parameters. It allows multiple sets of nested attributes to be included.
It does look a little odd, but that shouldn't be a concern. The nested attribute handler will know what to do with it. It's only ever an issue if you need to manipulate these before they're intercepted by the default handler, but that's best avoided.
So I am in the process of modeling/designing an academic test bank for users on my app, and I was wondering if there's some default Rails way to do something like this:
Essentially, the test bank will have subject categories (such as Math, History, English), and within each subject category, there will be folders for classes that correspond to the subject. (for instance, in the Math category, we would have subcategories Math 101, Math 128,Math 185, and so on. Finally, within the class categories, we would have the actual tests themselves (as PDFs).
I know the best thing to do is to have a TestFile model, declare that it has_attached_file (with Paperclip), and declare that ClassCategory has_many Tests. But I'm a bit confused on what associations to use everything else.
My guess:
TestBank.rb:
has_many SubjectCategory
SubjectCategory.rb
belongs_to TestBank
has_many ClassCategory
ClassCategory.rb
belongs_to SubjectCategory
has_many TestFile
TestFile.rb:
has_attached_file :pdf
belongs_to ClassCategory
Is this correct?
Furthermore, how do I work out all of the routing? If I recall, nesting resources more than 1 level deep is not ideal, so how would I work this out? Thanks.
That seems reasonable. As for the routing, what you are describing here are model assocations. Each of the models should have its own controller that you don't need to nest unless you want to. resources :controller_name in routes.rb will set up each controller without namespacing. Personally, I'd namespace like this:
/:subject_category/:class_category
From what I can tell you don't have a lot of information needed for the TestFile so I'd consider calling them via the association - i.e., Math 101 (a :class_category) has all the resources for Math 101 on its page, or loads them in via JS partials, perhaps. That's personal taste though. At work we've got a route nested 4 deep because it's most appropriate to generate a URL that looks correct given your location in the app. Not ideal, but it doesn't cause problems either.
You can set this up by using Ruby on rails' sweet association system, I've read your idea and decided to alter some classnames
resources:
Subject (Math, English etc.)
Category(M101, M128 etc.)
SubjectCategory(combines subject and category so category isn't restricted to 1 subject.)
Test
Association logic:
class Subject < ActiveRecord::Base
has_many :subject_categories
has_many :categories, through: :subject_categories
end
class Category < ActiveRecord::Base
has_many :subject_categories
has_many :subjects, through: :subject_categories
end
class SubjectCategory < ActiveRecord::Base
belongs_to :subject
belongs_to :category
has_many :tests
end
and as the combination of the 2 decides which tests are related:
class Test < ActiveRecord::Base
belongs_to :subject_category
mount_uploader :source, TestUploader // this is carrierwave related do your own thing here.
end
EDIT:
Also the routes:
resources :subjects do
resources :categories
resources :subject_categories, only: :create
end
for more info please refer to the rails guide:
http://guides.rubyonrails.org/association_basics.html
Happy coding :)
I'm working on an app that downloads meta tags from websites and saves then. The downloading happens in a model called Site. I'd like to save off the downloaded robots meta tags into a model called robots_tag which is connected to sites via a join table called meta_tag_sites.
But the method that I've written in the sites model to do this isn't working. When I try to call the method in the console, I get the following error.
undefined method `robots_meta=' for []:ActiveRecord::Relation
Any idea what I'm doing wrong?
class Site < ActiveRecord::Base
attr_accessible :domain
belongs_to :user
has_many :meta_tag_sites
has_many :robots_tags, through: :meta_tag_sites
accepts_nested_attributes_for :robots_tags
# ...
def download_robots_meta_tags
robots_tags = Nokogiri::HTML(Net::HTTP.get(self.domain, "/")).xpath("//meta[#name='robots']")
robots_tags.each do |tag|
self.robots_tags.robots_meta = tag
end
end
# ...
end
class RobotsTag < ActiveRecord::Base
attr_accessible :robots_meta
has_many :meta_tag_sites
has_many :sites, through: :meta_tag_sites
end
class MetaTagSite < ActiveRecord::Base
attr_accessible :site_id, :meta_tag_id
belongs_to :site
belongs_to :robots_tag
end
(BTW, this post is related to an earlier post: Web-scraping Rails App Getting Over-Modelled?).
The problem is here:
self.robots_tags.robots_meta = tag
self.robots_tags is a collection of objects defined by has_many :robots_tags, and you're attempting to assign a specific attribute to that entire collection. You can't do this. If you want to assign to an attribute on a specific object, you have to either iterate over the collection, or select a specific object from the collection via first or last or any of the other Enumerable methods.
By inspection, the offending line appears to be:
self.robots_tags.robots_meta = tag
You should iterate over self.robots_tags instead, with something like:
self.robots_tags.each do |robot_tag|
robot_tag.robots_meta = tag
end